update 2023-01-26 15:46:00

This commit is contained in:
github-actions[bot]
2023-01-26 15:46:00 +08:00
parent 1355a4d2ef
commit 4b132433f5
83 changed files with 16585 additions and 49 deletions

View File

@@ -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 <cnsztl@immortalwrt.org>
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))

View File

@@ -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-----

View File

@@ -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-----

View File

@@ -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-----

View File

@@ -0,0 +1,144 @@
From f4f5d11b578a1ab2c3d089bbe5453052b43892bb Mon Sep 17 00:00:00 2001
From: tofuliang <tofuliang@gmail.com>
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

View File

@@ -0,0 +1,29 @@
From 6c009953d357d1cc03478cf65fc05701fb1966d6 Mon Sep 17 00:00:00 2001
From: ameansone <ameansone@outlook.com>
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

View File

@@ -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 <cnsztl@immortalwrt.org>
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))

109
amule/Makefile Normal file
View File

@@ -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))

View File

@@ -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<CryptoPP::RSASSA_PKCS1v15_SHA_Signer *>(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

File diff suppressed because it is too large Load Diff

View File

@@ -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 <cstdlib> // Needed for std::abort()
-
+#include <exception>
#ifdef HAVE_CONFIG_H
# include "config.h" // Needed for HAVE_CXXABI and HAVE_EXECINFO
#endif
--
2.17.1

File diff suppressed because it is too large Load Diff

View File

@@ -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])

View File

@@ -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.

View File

@@ -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<CMemFile> 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

View File

@@ -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
"<UpnpSendActionAsync>");
}
/* 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(

View File

@@ -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;
}

View File

@@ -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();

55
baidupcs-web/Makefile Normal file
View File

@@ -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))

61
dnsforwarder/Makefile Normal file
View File

@@ -0,0 +1,61 @@
#
# Copyright (C) 2021 ImmortalWrt
# <https://immortalwrt.org>
#
# 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 <openwrt@tossp.com>
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))

View File

@@ -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'

File diff suppressed because it is too large Load Diff

View File

@@ -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='<!-- TS DNSFORWARDER -->'
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
}

View File

@@ -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>
DNS IP address for the GfwList Domains (Default: 127.0.0.1)
-p, --port <dns_port>
DNS Port for the GfwList Domains (Default: 5353)
-s, --ipset <ipset_name>
Ipset name for the GfwList domains
(If not given, ipset rules will not be generated.)
-o, --output <FILE>
/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 <FILE>
Delete specific domains in the result from a domain list text file
Please put one domain per line
--extra-domain-file <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 "$@"

50
gmediarender/Makefile Normal file
View File

@@ -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))

View File

@@ -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 <cnsztl@immortalwrt.org>
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))

View File

@@ -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'

View File

@@ -0,0 +1,50 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2021 Tianling Shen <cnsztl@immortalwrt.org>
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"
}

View File

@@ -0,0 +1,24 @@
# SPDX-License-Identifier: GPL-3.0-only
#
# Copyright (C) 2019-2022 Tianling Shen <cnsztl@immortalwrt.org>
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 <cnsztl@immortalwrt.org>
define Package/luci-app-unblockneteasemusic/conffiles
/etc/config/unblockneteasemusic
endef
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature

View File

@@ -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 = '<em><span style="color:%s"><strong>%s %s</strong></span></em>';
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] 等音源,替换网易云音乐 无版权/收费 歌曲链接<br/>' +
'具体使用方法参见:<a href="https://github.com/UnblockNeteaseMusic/luci-app-unblockneteasemusic" target="_blank">GitHub @UnblockNeteaseMusic/luci-app-unblockneteasemusic</a>'));
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', _('附加专辑名'),
_('在其他音源搜索歌曲时携带专辑名称(默认搜索条件 <code>歌曲名 - 歌手</code>,启用后搜索条件 <code>歌曲名 - 歌手 专辑名</code>)。'));
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', _('启用严格模式'),
_('若将服务部署到公网,则强烈建议使用严格模式,此模式下仅放行网易云音乐所属域名的请求。<br/>注意:该模式下不能使用全局代理。'));
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();
}
});

View File

@@ -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 = '<div style="color:%s;margin-top:5px;"><strong>%s</strong></div>';
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
});

View File

@@ -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'

View File

@@ -0,0 +1,242 @@
#!/bin/sh /etc/rc.common
# SPDX-License-Identifier: GPL-3.0-only
#
# Copyright (C) 2019-2023 Tianling Shen <cnsztl@immortalwrt.org>
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"
}

View File

@@ -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

View File

@@ -0,0 +1,16 @@
#!/bin/sh
# Copyright (C) 2021-2022 Tianling Shen <cnsztl@immortalwrt.org>
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"

View File

@@ -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"
}
}
}

View File

@@ -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" ]
}
}
}

View File

@@ -0,0 +1,104 @@
#!/bin/sh
# Copyright (C) 2021-2022 Tianling Shen <cnsztl@immortalwrt.org>
. /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."

View File

@@ -0,0 +1,11 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-3.0-only
# Copyright (C) 2019-2022 Tianling Shen <cnsztl@immortalwrt.org>
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}"

View File

@@ -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 %}

View File

@@ -0,0 +1,9 @@
{%
let hijack_ways = o_hijack_ways;
if (hijack_ways == "use_ipset") {
include("set.uc");
}
include("chain.uc");
%}

View File

@@ -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 %}

View File

@@ -0,0 +1,104 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-3.0-only
# Copyright (C) 2019-2023 Tianling Shen <cnsztl@immortalwrt.org>
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

80
miniupnpd/Makefile Normal file
View File

@@ -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 <fingon@iki.fi>
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))

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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"
}

View File

@@ -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"

View File

@@ -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)

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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;
}

51
msd_lite/Makefile Normal file
View File

@@ -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))

View File

@@ -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")

68
mwan3/Makefile Normal file
View File

@@ -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 <fe@dev.tdt.de>
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 <fe@dev.tdt.de>
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))

View File

@@ -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'

View File

@@ -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

View File

@@ -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

View File

@@ -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

28
mwan3/files/etc/init.d/mwan3 Executable file
View File

@@ -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'
}

View File

@@ -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
# <ifup> Is called by netifd and mwan3track
# <ifdown> Is called by netifd and mwan3track
# <connected> Is only called by mwan3track if tracking was successful
# <disconnected> 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")

View File

@@ -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

View File

@@ -0,0 +1,6 @@
#!/bin/sh
get_uptime() {
local uptime=$(cat /proc/uptime)
echo "${uptime%%.*}"
}

File diff suppressed because it is too large Load Diff

View File

@@ -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 "$@"

213
mwan3/files/usr/sbin/mwan3 Executable file
View File

@@ -0,0 +1,213 @@
#!/bin/sh
. /lib/functions.sh
. /usr/share/libubox/jshn.sh
. /lib/functions/network.sh
. /lib/mwan3/mwan3.sh
help()
{
cat <<EOF
Syntax: mwan3 [command]
Available commands:
start Load iptables rules, ip rules and ip routes
stop Unload iptables rules, ip rules and ip routes
restart Reload iptables rules, ip rules and ip routes
ifup <iface> Load rules and routes for specific interface
ifdown <iface> 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 <interface>" && exit 0
fi
if [ -n "$2" ]; then
echo "Error: Too many arguments. Usage: mwan3 ifdown <interface>" && 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 <interface>" && exit 0
fi
if [ -n "$2" ]; then
echo "Too many arguments. Usage: mwan3 ifup <interface>" && 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

38
mwan3/files/usr/sbin/mwan3rtmon Executable file
View File

@@ -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 "$@"

293
mwan3/files/usr/sbin/mwan3track Executable file
View File

@@ -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 "$@"

89
nps/Makefile Normal file
View File

@@ -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 <cnsztl@immortalwrt.org>
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))

View File

@@ -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

View File

@@ -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))

95
qBittorrent/Makefile Normal file
View File

@@ -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))

200
qtbase/Makefile Normal file
View File

@@ -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))

50
qttools/Makefile Normal file
View File

@@ -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))

62
rblibtorrent/Makefile Normal file
View File

@@ -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 <arvid@libtorrent.org>
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))

45
tcpping/Makefile Normal file
View File

@@ -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))

85
uugamebooster/Makefile Normal file
View File

@@ -0,0 +1,85 @@
#
# Copyright (C) 2021 KFERMercer <KFER.Mercer@gmail.com>
#
# 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))

View File

@@ -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

View File

@@ -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))