diff --git a/cdnspeedtest/Makefile b/cdnspeedtest/Makefile new file mode 100644 index 000000000..03ad33510 --- /dev/null +++ b/cdnspeedtest/Makefile @@ -0,0 +1,47 @@ +# SPDX-License-Identifier: GPL-3.0-only +# +# Copyright (C) 2021 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=CloudflareSpeedTest +PKG_VERSION:=2.1.0 +PKG_RELEASE:=$(AUTORELEASE) + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/XIU2/CloudflareSpeedTest/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=39a4e4a341330746a8bd0a07769663f08d2fcc9c216e52a8b5e40c3e03fe1b6f + +PKG_LICENSE:=GPL-3.0-only +PKG_LICENSE_FILE:=LICENSE +PKG_MAINTAINER:=Tianling Shen + +PKG_BUILD_DEPENDS:=golang/host +PKG_BUILD_PARALLEL:=1 +PKG_USE_MIPS16:=0 + +GO_PKG:=CloudflareSpeedTest +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/cdnspeedtest + SECTION:=net + CATEGORY:=Network + TITLE:=Getting the fastest ips to your network of CDN + URL:=https://github.com/XIU2/CloudflareSpeedTest + DEPENDS:=$(GO_ARCH_DEPENDS) +ca-bundle +endef + +define Package/cdnspeedtest/install + $(call GoPackage/Package/Install/Bin,$(PKG_INSTALL_DIR)) + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/CloudflareSpeedTest $(1)/usr/bin/cdnspeedtest + + $(INSTALL_DIR) $(1)/usr/share/CloudflareSpeedTest + $(INSTALL_DATA) $(PKG_BUILD_DIR)/ip.txt $(1)/usr/share/CloudflareSpeedTest/ + $(INSTALL_DATA) $(PKG_BUILD_DIR)/ipv6.txt $(1)/usr/share/CloudflareSpeedTest/ +endef + +$(eval $(call BuildPackage,cdnspeedtest)) diff --git a/filebrowser/Makefile b/filebrowser/Makefile new file mode 100644 index 000000000..47a6d7323 --- /dev/null +++ b/filebrowser/Makefile @@ -0,0 +1,68 @@ +# SPDX-License-Identifier: GPL-3.0-only +# +# Copyright (C) 2021 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=filebrowser +PKG_VERSION:=2.21.1 +PKG_RELEASE:=$(AUTORELEASE) + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_VERSION:=b73d278 +PKG_SOURCE_URL:=https://github.com/filebrowser/filebrowser +PKG_MIRROR_HASH:=66b9df31f98bec22715a7fe9ca73962c1e5a5c1b3bcfb99fd0ac1703118ee4c8 + +PKG_LICENSE:=Apache-2.0 +PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=CN_SZTL + +PKG_BUILD_DEPENDS:=golang/host node/host +PKG_BUILD_PARALLEL:=1 +PKG_USE_MIPS16:=0 + +GO_PKG:=github.com/filebrowser/filebrowser +GO_PKG_LDFLAGS_X:= \ + $(GO_PKG)/v2/version.CommitSHA=$(PKG_SOURCE_VERSION) \ + $(GO_PKG)/v2/version.Version=v$(PKG_VERSION) + +include $(INCLUDE_DIR)/package.mk +include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk + +define Package/filebrowser + SECTION:=utils + CATEGORY:=Utilities + TITLE:=Web File Browser + URL:=https://github.com/filebrowser/filebrowser + DEPENDS:=$(GO_ARCH_DEPENDS) +endef + +define Package/filebrowser/description + filebrowser provides a file managing interface within a specified directory + and it can be used to upload, delete, preview, rename and edit your files. + It allows the creation of multiple users and each user can have its own directory. + It can be used as a standalone app or as a middleware. +endef + +define Build/Compile + ( \ + pushd "$(PKG_BUILD_DIR)/frontend" ; \ + npm ci; \ + npm run lint ; \ + npm run build ; \ + popd ; \ + $(call GoPackage/Build/Compile) ; \ + ) +endef + +define Package/filebrowser/install + $(call GoPackage/Package/Install/Bin,$(1)) + + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) $(CURDIR)/files/filebrowser.config $(1)/etc/config/filebrowser + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) $(CURDIR)/files/filebrowser.init $(1)/etc/init.d/filebrowser +endef + +$(eval $(call GoBinPackage,filebrowser)) +$(eval $(call BuildPackage,filebrowser)) diff --git a/filebrowser/files/filebrowser.config b/filebrowser/files/filebrowser.config new file mode 100644 index 000000000..85eb6ac44 --- /dev/null +++ b/filebrowser/files/filebrowser.config @@ -0,0 +1,9 @@ + +config filebrowser 'config' + option addr_type 'lan' + option db_dir '/etc' + option db_name 'filebrowser.db' + option enabled '0' + option port '8989' + option root_dir '/' + diff --git a/filebrowser/files/filebrowser.init b/filebrowser/files/filebrowser.init new file mode 100755 index 000000000..dda404638 --- /dev/null +++ b/filebrowser/files/filebrowser.init @@ -0,0 +1,34 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2021 ImmortalWrt + +START=90 +STOP=10 + +addr_type="$(uci get filebrowser.config.addr_type)" +db_dir="$(uci get filebrowser.config.db_dir)" +[ "${db_dir}" == "/" ] || db_dir="${db_dir%*/}" +db_name="$(uci get filebrowser.config.db_name| sed 's#/##g')" +enabled="$(uci get filebrowser.config.enabled)" +port="$(uci get filebrowser.config.port)" +root_dir="$(uci get filebrowser.config.root_dir)" + +if [ "${addr_type}" == "local" ];then + addr="127.0.0.1" +elif [ "${addr_type}" == "lan" ];then + addr="$(uci get network.lan.ipaddr)" +elif [ "${addr_type}" == "wan" ];then + addr="0.0.0.0" +fi + +start() { + stop + [ "$enabled" == "1" ] || exit 0 + mkdir -p "${root_dir}" + mkdir -p "${db_dir}" + filebrowser -a "${addr}" -d "${db_dir}/${db_name}" -p "${port}" -r "${root_dir}" >/dev/null 2>&1 & +} + +stop() { + echo "${db_dir}/${db_name}" > "/lib/upgrade/keep.d/filebrowser" + killall -3 filebrowser >/dev/null 2>&1 +} diff --git a/homebox/Makefile b/homebox/Makefile new file mode 100644 index 000000000..16eea08b7 --- /dev/null +++ b/homebox/Makefile @@ -0,0 +1,85 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=homebox +PKG_VERSION:=0.0.0-dev.2020062901 +PKG_RELEASE:=14 + +PKG_SOURCE_URL_FILE:=v$(PKG_VERSION).tar.gz +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://github.com/XGHeaven/homebox/archive/refs/tags/ +PKG_HASH:=skip + +PKG_BUILD_DEPENDS:=golang/host homebox/host +PKG_BUILD_PARALLEL:=1 +PKG_USE_MIPS16:=0 + +HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/${PKG_NAME} + +include $(INCLUDE_DIR)/host-build.mk +include $(INCLUDE_DIR)/package.mk +include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk + +define Package/$(PKG_NAME) + SECTION:=net + CATEGORY:=Network + SUBMENU:=Web Servers/Proxies + TITLE:=A Toolbox for Home Local Networks + URL:=https://github.com/XGHeaven/homebox + DEPENDS:=$(GO_ARCH_DEPENDS) + MENU:=1 +endef + +define Package/$(PKG_NAME)/description + A Toolbox for Home Local Networks Speed Test +endef + +GO_PKG_BUILD_VARS += GO111MODULE=auto +TAR_OPTIONS:=--strip-components 1 $(TAR_OPTIONS) +TAR_CMD=$(HOST_TAR) -C $(1) $(TAR_OPTIONS) + +define Build/Configure + ( \ + cd $(PKG_BUILD_DIR)/server; \ + $(GO_PKG_VARS) \ + go get -d -modcacherw; \ + ) + ( \ + cd $(PKG_BUILD_DIR)/server; \ + GOPATH=$(PKG_BUILD_DIR)/.go_work/build \ + go install -modcacherw github.com/go-bindata/go-bindata/...@latest; \ + ) +endef + +define Build/Compile + rm -rf $(PKG_BUILD_DIR)/build/static + mkdir -p $(PKG_BUILD_DIR)/build + $(CP) $(HOST_BUILD_DIR)/build/static $(PKG_BUILD_DIR)/build/ + ( \ + cd $(PKG_BUILD_DIR); \ + $(GO_PKG_VARS) PATH=$(PKG_BUILD_DIR)/.go_work/build/bin:$$$$PATH \ + $(MAKE) build-server; \ + ) +endef + +define Package/$(PKG_NAME)/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/build/server $(1)/usr/bin/homebox +endef + +define Host/Configure + cd $(HOST_BUILD_DIR)/web && rm -f package-lock.json && npm --cache-min 1440 install +endef + +define Host/Compile + cd $(HOST_BUILD_DIR) && $(MAKE) build-web +endef + +define Host/Install +endef + +define Host/Clean + rm -f $(HOST_BUILD_DIR)/build/static +endef + +$(eval $(call HostBuild)) +$(eval $(call BuildPackage,homebox)) diff --git a/luci-app-msd_lite/Makefile b/luci-app-msd_lite/Makefile new file mode 100644 index 000000000..778a9862d --- /dev/null +++ b/luci-app-msd_lite/Makefile @@ -0,0 +1,11 @@ +# Copyright (C) 2022 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=LuCI support for Multi stream daemon lite +LUCI_DEPENDS:=+msd_lite +LUCI_PKGARCH:=all + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js b/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js new file mode 100644 index 000000000..c0868ed51 --- /dev/null +++ b/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js @@ -0,0 +1,66 @@ +/* Copyright (C) 2022 ImmortalWrt.org */ + +'use strict'; +'require view'; +'require form'; +'require tools.widgets as widgets'; + +return view.extend({ + render: function () { + var m, s, o; + + m = new form.Map('msd_lite', _('Multi Stream daemon Lite'), + _('The lightweight version of Multi Stream daemon (msd) Program for organizing IP TV streaming on the network via HTTP.')); + + s = m.section(form.TypedSection, 'instance'); + s.anonymous = true; + s.addremove = true; + s.addbtntitle = _('Add instance'); + + o = s.option(form.Flag, 'enabled', _('Enable')); + o.default = o.disabled; + o.rmempty = false; + + o = s.option(form.DynamicList, 'address', _('Bind address')); + o.datatype = 'ipaddrport(1)'; + o.rmempty = false; + + o = s.option(widgets.DeviceSelect, 'interface', _('Source interface'), + _('For multicast receive.')); + o.noaliases = true; + o.nocreate = true; + o.optional = true; + + o = s.option(form.Value, 'threads', _('Worker threads'), + _('Leave 0 or empty to auto detect.')); + o.datatype = 'uinteger'; + o.default = '0'; + + o = s.option(form.Flag, 'bind_to_cpu', _('Bind threads to CPUs')); + o.default = o.disabled; + + o = s.option(form.Flag, 'drop_slow_clients', _('Disconnect slow clients')); + o.default = o.disabled; + + o = s.option(form.Value, 'precache_size', _('Pre cache size')); + o.datatype = 'uinteger'; + o.default = '4096'; + + o = s.option(form.Value, 'ring_buffer_size', _('Ring buffer size'), + _('Stream receive ring buffer size.')); + o.datatype = 'uinteger'; + o.default = '1024'; + + o = s.option(form.Value, 'multicast_recv_buffer_size', _('Receive buffer size'), + _('Multicast receive socket buffer size.')); + o.datatype = 'uinteger'; + o.default = '512'; + + o = s.option(form.Value, 'multicast_recv_timeout', _('Receive timeout'), + _('Multicast receive timeout.')); + o.datatype = 'uinteger'; + o.default = '2'; + + return m.render(); + } +}); diff --git a/luci-app-msd_lite/po/templates/msd_lite.pot b/luci-app-msd_lite/po/templates/msd_lite.pot new file mode 100644 index 000000000..12e403e2a --- /dev/null +++ b/luci-app-msd_lite/po/templates/msd_lite.pot @@ -0,0 +1,81 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:18 +msgid "Add instance" +msgstr "" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:24 +msgid "Bind address" +msgstr "" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:39 +msgid "Bind threads to CPUs" +msgstr "" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:42 +msgid "Disconnect slow clients" +msgstr "" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:20 +msgid "Enable" +msgstr "" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:29 +msgid "For multicast receive." +msgstr "" + +#: applications/luci-app-msd_lite/root/usr/share/rpcd/acl.d/luci-app-msd_lite.json:3 +msgid "Grant UCI access for luci-app-msd_lite" +msgstr "" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:35 +msgid "Leave 0 or empty to auto detect." +msgstr "" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:12 +#: applications/luci-app-msd_lite/root/usr/share/luci/menu.d/luci-app-msd_lite.json:3 +msgid "Multi Stream daemon Lite" +msgstr "" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:55 +msgid "Multicast receive socket buffer size." +msgstr "" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:60 +msgid "Multicast receive timeout." +msgstr "" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:45 +msgid "Pre cache size" +msgstr "" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:54 +msgid "Receive buffer size" +msgstr "" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:59 +msgid "Receive timeout" +msgstr "" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:49 +msgid "Ring buffer size" +msgstr "" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:28 +msgid "Source interface" +msgstr "" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:50 +msgid "Stream receive ring buffer size." +msgstr "" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:13 +msgid "" +"The lightweight version of Multi Stream daemon (msd) Program for organizing " +"IP TV streaming on the network via HTTP." +msgstr "" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:34 +msgid "Worker threads" +msgstr "" diff --git a/luci-app-msd_lite/po/zh-cn b/luci-app-msd_lite/po/zh-cn new file mode 120000 index 000000000..8d69574dd --- /dev/null +++ b/luci-app-msd_lite/po/zh-cn @@ -0,0 +1 @@ +zh_Hans \ No newline at end of file diff --git a/luci-app-msd_lite/po/zh_Hans/msd_lite.po b/luci-app-msd_lite/po/zh_Hans/msd_lite.po new file mode 100644 index 000000000..b9f45e22b --- /dev/null +++ b/luci-app-msd_lite/po/zh_Hans/msd_lite.po @@ -0,0 +1,90 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Project-Id-Version: PACKAGE VERSION\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: zh-Hans\n" +"MIME-Version: 1.0\n" +"Content-Transfer-Encoding: 8bit\n" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:18 +msgid "Add instance" +msgstr "添加实例" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:24 +msgid "Bind address" +msgstr "绑定地址" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:39 +msgid "Bind threads to CPUs" +msgstr "绑定线程到 CPU" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:42 +msgid "Disconnect slow clients" +msgstr "断开慢速客户端" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:20 +msgid "Enable" +msgstr "启用" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:29 +msgid "For multicast receive." +msgstr "用于接收组播流。" + +#: applications/luci-app-msd_lite/root/usr/share/rpcd/acl.d/luci-app-msd_lite.json:3 +msgid "Grant UCI access for luci-app-msd_lite" +msgstr "授予 luci-app-msd_lite 访问 UCI 配置的权限。" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:35 +msgid "Leave 0 or empty to auto detect." +msgstr "保留为 0 或留空以自动检测。" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:12 +#: applications/luci-app-msd_lite/root/usr/share/luci/menu.d/luci-app-msd_lite.json:3 +msgid "Multi Stream daemon Lite" +msgstr "组播转换 Lite" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:55 +msgid "Multicast receive socket buffer size." +msgstr "组播接收套接字缓冲区大小。" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:60 +msgid "Multicast receive timeout." +msgstr "组播接收超时。" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:45 +msgid "Pre cache size" +msgstr "预缓存大小" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:54 +msgid "Receive buffer size" +msgstr "接收缓冲区大小" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:59 +msgid "Receive timeout" +msgstr "接收超时" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:49 +msgid "Ring buffer size" +msgstr "环形缓冲区大小" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:28 +msgid "Source interface" +msgstr "源接口" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:50 +msgid "Stream receive ring buffer size." +msgstr "流接收环形缓冲区大小。" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:13 +msgid "" +"The lightweight version of Multi Stream daemon (msd) Program for organizing " +"IP TV streaming on the network via HTTP." +msgstr "" +"Multi Stream daemon (msd) 程序的轻量级版本,用于通过 HTTP 管理网络上的 IP TV " +"流。" + +#: applications/luci-app-msd_lite/htdocs/luci-static/resources/view/msd_lite.js:34 +msgid "Worker threads" +msgstr "工作线程" diff --git a/luci-app-msd_lite/root/usr/share/luci/menu.d/luci-app-msd_lite.json b/luci-app-msd_lite/root/usr/share/luci/menu.d/luci-app-msd_lite.json new file mode 100644 index 000000000..a7e389d34 --- /dev/null +++ b/luci-app-msd_lite/root/usr/share/luci/menu.d/luci-app-msd_lite.json @@ -0,0 +1,13 @@ +{ + "admin/services/msd_lite": { + "title": "Multi Stream daemon Lite", + "action": { + "type": "view", + "path": "msd_lite" + }, + "depends": { + "acl": [ "luci-app-msd_lite" ], + "uci": { "msd_lite": true } + } + } +} diff --git a/luci-app-msd_lite/root/usr/share/rpcd/acl.d/luci-app-msd_lite.json b/luci-app-msd_lite/root/usr/share/rpcd/acl.d/luci-app-msd_lite.json new file mode 100644 index 000000000..ef1c345eb --- /dev/null +++ b/luci-app-msd_lite/root/usr/share/rpcd/acl.d/luci-app-msd_lite.json @@ -0,0 +1,11 @@ +{ + "luci-app-msd_lite": { + "description": "Grant UCI access for luci-app-msd_lite", + "read": { + "uci": [ "msd_lite" ] + }, + "write": { + "uci": [ "msd_lite" ] + } + } +} diff --git a/v2ray-geodata/Makefile b/v2ray-geodata/Makefile index ce38fbab9..11756a212 100644 --- a/v2ray-geodata/Makefile +++ b/v2ray-geodata/Makefile @@ -12,22 +12,22 @@ PKG_MAINTAINER:=Tianling Shen include $(INCLUDE_DIR)/package.mk -GEOIP_VER:=202301190046 +GEOIP_VER:=202301260045 GEOIP_FILE:=geoip.dat.$(GEOIP_VER) define Download/geoip URL:=https://github.com/v2fly/geoip/releases/download/$(GEOIP_VER)/ URL_FILE:=geoip.dat FILE:=$(GEOIP_FILE) - HASH:=a8dc0a78cfec5be8735fa2143d61eccb59ec9fd813067dbb6434dc3d07b1b664 + HASH:=a13a2ca90c15a85f4cc8169d12be24cb71f34bb75eb446000d9ec18ebefd2511 endef -GEOSITE_VER:=20230118150903 +GEOSITE_VER:=20230122133243 GEOSITE_FILE:=dlc.dat.$(GEOSITE_VER) define Download/geosite URL:=https://github.com/v2fly/domain-list-community/releases/download/$(GEOSITE_VER)/ URL_FILE:=dlc.dat FILE:=$(GEOSITE_FILE) - HASH:=a3ee2294c03d2ff1ab21aca408330147f1b3b65624eb329bae0f5e346a8b75bb + HASH:=6de6a932690d4e7cd04fc8c7883329fae8ed1323a8e0940f6dfa3c6f1bd9dee5 endef define Package/v2ray-geodata/template diff --git a/v2raya/Makefile b/v2raya/Makefile new file mode 100644 index 000000000..2f6828a2e --- /dev/null +++ b/v2raya/Makefile @@ -0,0 +1,89 @@ +# SPDX-License-Identifier: GPL-3.0-only +# +# Copyright (C) 2021 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +PKG_NAME:=v2rayA +PKG_VERSION:=1.5.9.1698.1 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/v2rayA/v2rayA/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=247a357230c616bf48309c61d119686e4ad56939c05afef584c45051e9dc6220 +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)/service + +PKG_LICENSE:=AGPL-3.0-only +PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=Tianling Shen + +PKG_BUILD_DEPENDS:=golang/host +PKG_BUILD_PARALLEL:=1 +PKG_USE_MIPS16:=0 + +GO_PKG:=github.com/v2rayA/v2rayA +GO_PKG_LDFLAGS_X:=$(GO_PKG)/conf.Version=$(PKG_VERSION) + +include $(INCLUDE_DIR)/package.mk +include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk + +TAR_OPTIONS+= --strip-components 1 +TAR_CMD=$(HOST_TAR) -C $(1)/.. $(TAR_OPTIONS) + +define Package/v2raya + TITLE:=A Linux web GUI client of Project V + SECTION:=net + CATEGORY:=Network + SUBMENU:=Web Servers/Proxies + DEPENDS:=$(GO_ARCH_DEPENDS) \ + +ca-bundle \ + +iptables-mod-conntrack-extra \ + +iptables-mod-extra \ + +iptables-mod-filter \ + +iptables-mod-tproxy \ + +kmod-ipt-nat6 \ + +xray-core + URL:=https://v2raya.org +endef + +define Package/v2raya/description + v2rayA is a V2Ray Linux client supporting global transparent proxy, + compatible with SS, SSR, Trojan(trojan-go), PingTunnel protocols. +endef + +define Package/v2raya/conffiles +/etc/v2raya/ +/etc/config/v2raya +endef + +WEB_FILE:=$(PKG_NAME)-web-$(PKG_VERSION).tar.gz +define Download/v2raya-web + URL:=https://codeload.github.com/v2rayA/v2raya-web/tar.gz/v$(PKG_VERSION)? + URL_FILE:=$(WEB_FILE) + FILE:=$(WEB_FILE) + HASH:=149097a42c3e5fa6f5c3cd46d1bf7ec4546e79ad37c1446b759539e700bd75e2 +endef + +define Build/Prepare + $(call Build/Prepare/Default) + + ( \ + mkdir -p $(PKG_BUILD_DIR)/server/router/web ; \ + gzip -dc $(DL_DIR)/$(WEB_FILE) | $(HOST_TAR) -C $(PKG_BUILD_DIR)/server/router/web $(TAR_OPTIONS) ; \ + ) +endef + +define Package/v2raya/install + $(call GoPackage/Package/Install/Bin,$(PKG_INSTALL_DIR)) + $(INSTALL_DIR) $(1)/usr/bin/ + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/v2rayA $(1)/usr/bin/v2raya + + $(INSTALL_DIR) $(1)/etc/config/ + $(INSTALL_CONF) $(CURDIR)/files/v2raya.config $(1)/etc/config/v2raya + $(INSTALL_DIR) $(1)/etc/init.d/ + $(INSTALL_BIN) $(CURDIR)/files/v2raya.init $(1)/etc/init.d/v2raya +endef + +$(eval $(call Download,v2raya-web)) +$(eval $(call GoBinPackage,v2raya)) +$(eval $(call BuildPackage,v2raya)) diff --git a/v2raya/files/v2raya.config b/v2raya/files/v2raya.config new file mode 100644 index 000000000..d9ff36581 --- /dev/null +++ b/v2raya/files/v2raya.config @@ -0,0 +1,50 @@ + +config v2raya 'config' + option enabled '0' + + # Listening address + option address '0.0.0.0:2017' + + # v2rayA configuration directory + option config '/etc/v2raya' + + # Make sure your IPv6 network works fine before you turn it on. + # Optional values: auto, on, off. + option ipv6_support 'auto' + + # Optional values: trace, debug, info, warn or error + option log_level 'info' + + # The path of log file + option log_file '/var/log/v2raya/v2raya.log' + + # Maximum number of days to keep log files + option log_max_days '3' + + option log_disable_color '1' + + option log_disable_timestamp '0' + + # Executable v2ray binary path. Auto-detect if put it empty + option v2ray_bin '' + + # Additional v2ray config directory, files in it will be combined with config generated by v2rayA + option v2ray_confdir '' + + # The executable file to run in the transparent proxy life-cycle. + # v2rayA will pass in the --transparent-type (tproxy, redirect) + # and --stage (pre-start, post-start, pre-stop, post-stop) arguments. + option transparent_hook '' + + # The executable file to run in the v2ray-core life-cycle. + # v2rayA will pass in the --stage (pre-start, post-start, pre-stop, post-stop) argument. + option core_hook '' + + # The executable file to run in the v2ray-core life-cycle. + # v2rayA will pass in the --stage (pre-start, post-start, pre-stop, post-stop) argument. + option plugin_manager '' + + # Specify the certification path instead of automatically generating a self-signed certificate. + # Example: /etc/v2raya/grpc_certificate.crt,/etc/v2raya/grpc_private.key + option vless_grpc_inbound_cert_key '' + diff --git a/v2raya/files/v2raya.init b/v2raya/files/v2raya.init new file mode 100755 index 000000000..4120e90ff --- /dev/null +++ b/v2raya/files/v2raya.init @@ -0,0 +1,74 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2021 Tianling Shen + +USE_PROCD=1 +START=99 + +CONF="v2raya" +PROG="/usr/bin/v2raya" + +is_enabled() { + local enabled + config_get_bool enabled "$1" "$2" "${3:-0}" + if [ "$enabled" -eq "1" ]; then + return 0 + else + return 1 + fi +} + +append_env() { + procd_append_param env "V2RAYA_$(echo "$1" | tr "[a-z]" "[A-Z]")"="$2" +} + +append_env_arg() { + local value + config_get value "$1" "$2" $3 + [ -n "$value" ] && append_env "$2" "$value" +} + +append_env_bool() { + is_enabled "$1" "$2" && append_env "$2" "true" +} + +start_service() { + config_load "$CONF" + + is_enabled "config" "enabled" || return 1 + + procd_open_instance "$CONF" + procd_set_param command "$PROG" + procd_set_param env XDG_DATA_HOME="/usr/share" + + append_env_arg "config" "address" "0.0.0.0:2017" + append_env_arg "config" "config" "/etc/v2raya" + append_env_arg "config" "ipv6_support" "auto" + append_env_arg "config" "log_level" "info" + append_env_arg "config" "log_file" "/var/log/v2raya/v2raya.log" + append_env_arg "config" "log_max_days" "3" + append_env_arg "config" "v2ray_bin" + append_env_arg "config" "v2ray_confdir" + append_env_arg "config" "transparent_hook" + append_env_arg "config" "core_hook" + append_env_arg "config" "plugin_manager" + append_env_arg "config" "vless_grpc_inbound_cert_key" + append_env_bool "config" "log_disable_color" + append_env_bool "config" "log_disable_timestamp" + + procd_set_param limits core="unlimited" + procd_set_param limits nofile="1000000 1000000" + procd_set_param respawn + procd_set_param stdout 1 + procd_set_param stderr 1 + + procd_close_instance +} + +reload_service() { + stop + start +} + +service_triggers() { + procd_add_reload_trigger "$CONF" +} diff --git a/v2raya/patches/010-fixed-for-Docker-Compose.patch b/v2raya/patches/010-fixed-for-Docker-Compose.patch new file mode 100644 index 000000000..8461660f7 --- /dev/null +++ b/v2raya/patches/010-fixed-for-Docker-Compose.patch @@ -0,0 +1,46 @@ +From 78336e55a31db578c139a5bb472aa0fc219c169d Mon Sep 17 00:00:00 2001 +From: Xiaoxu Guo +Date: Thu, 4 Aug 2022 16:24:04 +0800 +Subject: [PATCH] fixed for Docker Compose + +--- + service/core/iptables/tproxy.go | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/core/iptables/tproxy.go ++++ b/core/iptables/tproxy.go +@@ -65,6 +65,7 @@ iptables -w 2 -t mangle -A TP_PRE -p udp + + iptables -w 2 -t mangle -A TP_RULE -j CONNMARK --restore-mark + iptables -w 2 -t mangle -A TP_RULE -m mark --mark 0x40/0xc0 -j RETURN ++iptables -w 2 -t mangle -A TP_RULE -i br+ -j RETURN + iptables -w 2 -t mangle -A TP_RULE -i docker+ -j RETURN + iptables -w 2 -t mangle -A TP_RULE -i veth+ -j RETURN + ` +@@ -123,6 +124,8 @@ ip6tables -w 2 -t mangle -A TP_PRE -p ud + + ip6tables -w 2 -t mangle -A TP_RULE -j CONNMARK --restore-mark + ip6tables -w 2 -t mangle -A TP_RULE -m mark --mark 0x40/0xc0 -j RETURN ++ip6tables -w 2 -t mangle -A TP_RULE -m mark --mark 0x40/0xc0 -j RETURN ++ip6tables -w 2 -t mangle -A TP_RULE -i br+ -j RETURN + ip6tables -w 2 -t mangle -A TP_RULE -i docker+ -j RETURN + ip6tables -w 2 -t mangle -A TP_RULE -i veth+ -j RETURN + ` +@@ -156,7 +159,7 @@ ip6tables -w 2 -t mangle -A TP_MARK -j C + + func (t *tproxy) GetCleanCommands() Setter { + commands := ` +-ip rule del fwmark 0x40/0xc0 table 100 ++ip rule del fwmark 0x40/0xc0 table 100 + ip route del local 0.0.0.0/0 dev lo table 100 + + iptables -w 2 -t mangle -F TP_OUT +@@ -172,7 +175,7 @@ iptables -w 2 -t mangle -X TP_MARK + ` + if IsIPv6Supported() { + commands += ` +-ip -6 rule del fwmark 0x40/0xc0 table 100 ++ip -6 rule del fwmark 0x40/0xc0 table 100 + ip -6 route del local ::/0 dev lo table 100 + + ip6tables -w 2 -t mangle -F TP_OUT diff --git a/v2raya/patches/011-cleaned-up.patch b/v2raya/patches/011-cleaned-up.patch new file mode 100644 index 000000000..74dc502ec --- /dev/null +++ b/v2raya/patches/011-cleaned-up.patch @@ -0,0 +1,37 @@ +From 0db405f50fd652d494f2066fc5e47c41666c96db Mon Sep 17 00:00:00 2001 +From: Xiaoxu Guo +Date: Thu, 4 Aug 2022 16:32:42 +0800 +Subject: [PATCH] cleaned up + +--- + service/core/iptables/tproxy.go | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/core/iptables/tproxy.go ++++ b/core/iptables/tproxy.go +@@ -124,7 +124,6 @@ ip6tables -w 2 -t mangle -A TP_PRE -p ud + + ip6tables -w 2 -t mangle -A TP_RULE -j CONNMARK --restore-mark + ip6tables -w 2 -t mangle -A TP_RULE -m mark --mark 0x40/0xc0 -j RETURN +-ip6tables -w 2 -t mangle -A TP_RULE -m mark --mark 0x40/0xc0 -j RETURN + ip6tables -w 2 -t mangle -A TP_RULE -i br+ -j RETURN + ip6tables -w 2 -t mangle -A TP_RULE -i docker+ -j RETURN + ip6tables -w 2 -t mangle -A TP_RULE -i veth+ -j RETURN +@@ -159,7 +158,7 @@ ip6tables -w 2 -t mangle -A TP_MARK -j C + + func (t *tproxy) GetCleanCommands() Setter { + commands := ` +-ip rule del fwmark 0x40/0xc0 table 100 ++ip rule del fwmark 0x40/0xc0 table 100 + ip route del local 0.0.0.0/0 dev lo table 100 + + iptables -w 2 -t mangle -F TP_OUT +@@ -175,7 +174,7 @@ iptables -w 2 -t mangle -X TP_MARK + ` + if IsIPv6Supported() { + commands += ` +-ip -6 rule del fwmark 0x40/0xc0 table 100 ++ip -6 rule del fwmark 0x40/0xc0 table 100 + ip -6 route del local ::/0 dev lo table 100 + + ip6tables -w 2 -t mangle -F TP_OUT diff --git a/v2raya/patches/012-improved.patch b/v2raya/patches/012-improved.patch new file mode 100644 index 000000000..1c755d015 --- /dev/null +++ b/v2raya/patches/012-improved.patch @@ -0,0 +1,38 @@ +From 4a87a6fc9a17939cc0fc54058b2128b1f688045a Mon Sep 17 00:00:00 2001 +From: Xiaoxu Guo +Date: Thu, 4 Aug 2022 22:56:46 +0800 +Subject: [PATCH] improved + +--- + service/core/iptables/tproxy.go | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/core/iptables/tproxy.go ++++ b/core/iptables/tproxy.go +@@ -16,7 +16,7 @@ var Tproxy tproxy + func (t *tproxy) AddIPWhitelist(cidr string) { + // avoid duplication + t.RemoveIPWhitelist(cidr) +- pos := 5 ++ pos := 6 + if configure.GetSettingNotNil().AntiPollution != configure.AntipollutionClosed { + pos += 3 + } +@@ -65,7 +65,7 @@ iptables -w 2 -t mangle -A TP_PRE -p udp + + iptables -w 2 -t mangle -A TP_RULE -j CONNMARK --restore-mark + iptables -w 2 -t mangle -A TP_RULE -m mark --mark 0x40/0xc0 -j RETURN +-iptables -w 2 -t mangle -A TP_RULE -i br+ -j RETURN ++iptables -w 2 -t mangle -A TP_RULE -i br-+ -j RETURN + iptables -w 2 -t mangle -A TP_RULE -i docker+ -j RETURN + iptables -w 2 -t mangle -A TP_RULE -i veth+ -j RETURN + ` +@@ -124,7 +124,7 @@ ip6tables -w 2 -t mangle -A TP_PRE -p ud + + ip6tables -w 2 -t mangle -A TP_RULE -j CONNMARK --restore-mark + ip6tables -w 2 -t mangle -A TP_RULE -m mark --mark 0x40/0xc0 -j RETURN +-ip6tables -w 2 -t mangle -A TP_RULE -i br+ -j RETURN ++ip6tables -w 2 -t mangle -A TP_RULE -i br-+ -j RETURN + ip6tables -w 2 -t mangle -A TP_RULE -i docker+ -j RETURN + ip6tables -w 2 -t mangle -A TP_RULE -i veth+ -j RETURN + ` diff --git a/v2raya/patches/013-fix-we-should-skip-interface-ppp-to-avoid-to-break-net.patch b/v2raya/patches/013-fix-we-should-skip-interface-ppp-to-avoid-to-break-net.patch new file mode 100644 index 000000000..0ff5f6a54 --- /dev/null +++ b/v2raya/patches/013-fix-we-should-skip-interface-ppp-to-avoid-to-break-net.patch @@ -0,0 +1,38 @@ +From ca6a05273284daa04856a840e64f3936f700b7c3 Mon Sep 17 00:00:00 2001 +From: mzz2017 +Date: Fri, 16 Sep 2022 15:13:11 +0800 +Subject: [PATCH] fix: we should skip interface ppp+ to avoid to break net + +--- + service/core/iptables/tproxy.go | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/core/iptables/tproxy.go ++++ b/core/iptables/tproxy.go +@@ -16,7 +16,7 @@ var Tproxy tproxy + func (t *tproxy) AddIPWhitelist(cidr string) { + // avoid duplication + t.RemoveIPWhitelist(cidr) +- pos := 6 ++ pos := 8 + if configure.GetSettingNotNil().AntiPollution != configure.AntipollutionClosed { + pos += 3 + } +@@ -68,6 +68,8 @@ iptables -w 2 -t mangle -A TP_RULE -m ma + iptables -w 2 -t mangle -A TP_RULE -i br-+ -j RETURN + iptables -w 2 -t mangle -A TP_RULE -i docker+ -j RETURN + iptables -w 2 -t mangle -A TP_RULE -i veth+ -j RETURN ++iptables -w 2 -t mangle -A TP_RULE -i ppp+ -j RETURN ++iptables -w 2 -t mangle -A TP_RULE -i dn42-+ -j RETURN + ` + if configure.GetSettingNotNil().AntiPollution != configure.AntipollutionClosed { + commands += ` +@@ -127,6 +129,8 @@ ip6tables -w 2 -t mangle -A TP_RULE -m m + ip6tables -w 2 -t mangle -A TP_RULE -i br-+ -j RETURN + ip6tables -w 2 -t mangle -A TP_RULE -i docker+ -j RETURN + ip6tables -w 2 -t mangle -A TP_RULE -i veth+ -j RETURN ++ip6tables -w 2 -t mangle -A TP_RULE -i ppp+ -j RETURN ++ip6tables -w 2 -t mangle -A TP_RULE -i dn42-+ -j RETURN + ` + if configure.GetSettingNotNil().AntiPollution != configure.AntipollutionClosed { + commands += ` diff --git a/v2raya/patches/014-fix-seed-cannot-be-read-from-vless-sharing-link-and-add-m.patch b/v2raya/patches/014-fix-seed-cannot-be-read-from-vless-sharing-link-and-add-m.patch new file mode 100644 index 000000000..ba5030624 --- /dev/null +++ b/v2raya/patches/014-fix-seed-cannot-be-read-from-vless-sharing-link-and-add-m.patch @@ -0,0 +1,105 @@ +From 5db722b22b39642280572a62b149d4e1efa21ce3 Mon Sep 17 00:00:00 2001 +From: mzz2017 +Date: Mon, 8 Aug 2022 22:30:36 +0800 +Subject: [PATCH] fix: seed cannot be read from vless sharing-link and add + missing sni field. #616 + +--- + service/core/serverObj/v2ray.go | 24 +++++++++++------------- + 1 file changed, 11 insertions(+), 13 deletions(-) + +--- a/core/serverObj/v2ray.go ++++ b/core/serverObj/v2ray.go +@@ -12,7 +12,6 @@ import ( + "time" + + jsoniter "github.com/json-iterator/go" +- "github.com/tidwall/gjson" + "github.com/v2rayA/v2rayA/common" + "github.com/v2rayA/v2rayA/core/coreObj" + "github.com/v2rayA/v2rayA/core/v2ray/service" +@@ -39,6 +38,7 @@ type V2Ray struct { + Net string `json:"net"` + Type string `json:"type"` + Host string `json:"host"` ++ SNI string `json:"sni"` + Path string `json:"path"` + TLS string `json:"tls"` + Flow string `json:"flow,omitempty"` +@@ -69,7 +69,8 @@ func ParseVlessURL(vless string) (data * + ID: u.User.String(), + Net: u.Query().Get("type"), + Type: u.Query().Get("headerType"), +- Host: u.Query().Get("sni"), ++ Host: u.Query().Get("host"), ++ SNI: u.Query().Get("sni"), + Path: u.Query().Get("path"), + TLS: u.Query().Get("security"), + Flow: u.Query().Get("flow"), +@@ -86,16 +87,13 @@ func ParseVlessURL(vless string) (data * + if data.Type == "" { + data.Type = "none" + } +- if data.Host == "" { +- data.Host = u.Query().Get("host") +- } + if data.TLS == "" { + data.TLS = "none" + } + if data.Flow == "" { + data.Flow = "xtls-rprx-direct" + } +- if data.Type == "mkcp" || data.Type == "kcp" { ++ if data.Net == "mkcp" || data.Net == "kcp" { + data.Path = u.Query().Get("seed") + } + return data, nil +@@ -145,6 +143,7 @@ func ParseVmessURL(vmess string) (data * + if aid == "" { + aid = q.Get("aid") + } ++ sni := q.Get("sni") + info = V2Ray{ + ID: subMatch[1], + Add: subMatch[2], +@@ -152,6 +151,7 @@ func ParseVmessURL(vmess string) (data * + Ps: ps, + Host: obfsParam, + Path: path, ++ SNI: sni, + Net: obfs, + Aid: aid, + TLS: map[string]string{"1": "tls"}[q.Get("tls")], +@@ -165,12 +165,6 @@ func ParseVmessURL(vmess string) (data * + if err != nil { + return + } +- if info.Host == "" { +- sni := gjson.Get(raw, "sni") +- if sni.Exists() { +- info.Host = sni.String() +- } +- } + } + // correct the wrong vmess as much as possible + if strings.HasPrefix(info.Host, "/") && info.Path == "" { +@@ -328,7 +322,9 @@ func (v *V2Ray) Configuration(info Prior + core.StreamSettings.TLSSettings.AllowInsecure = true + } + // SNI +- if v.Host != "" { ++ if v.SNI != "" { ++ core.StreamSettings.TLSSettings.ServerName = v.SNI ++ } else if v.Host != "" { + core.StreamSettings.TLSSettings.ServerName = v.Host + } + // Alpn +@@ -345,6 +341,8 @@ func (v *V2Ray) Configuration(info Prior + // SNI + if v.Host != "" { + core.StreamSettings.XTLSSettings.ServerName = v.Host ++ } else if v.Host != "" { ++ core.StreamSettings.TLSSettings.ServerName = v.Host + } + if v.AllowInsecure { + core.StreamSettings.XTLSSettings.AllowInsecure = true diff --git a/v2raya/patches/015-fix-a-problem-that-supervisor-cannot-exit-normally.patch b/v2raya/patches/015-fix-a-problem-that-supervisor-cannot-exit-normally.patch new file mode 100644 index 000000000..5447dc0f9 --- /dev/null +++ b/v2raya/patches/015-fix-a-problem-that-supervisor-cannot-exit-normally.patch @@ -0,0 +1,100 @@ +From 3f78422f81f3abc2668fc3938b31d213bfe4dfff Mon Sep 17 00:00:00 2001 +From: mzz2017 +Date: Sun, 28 Aug 2022 17:54:36 +0800 +Subject: [PATCH] fix: a problem that supervisor cannot exit normally + +--- + service/core/specialMode/infra/handle.go | 11 ++++++---- + service/core/specialMode/infra/supervisor.go | 22 ++++++++------------ + 2 files changed, 16 insertions(+), 17 deletions(-) + +--- a/core/specialMode/infra/handle.go ++++ b/core/specialMode/infra/handle.go +@@ -127,10 +127,13 @@ func (interfaceHandle *handle) handleRec + return results, msg + } + +-func packetFilter(portCache *portCache, pPacket *gopacket.Packet, whitelistDnsServers *v2router.GeoIPMatcher) (m *dnsmessage.Message, pSAddr, pSPort, pDAddr, pDPort *gopacket.Endpoint) { +- packet := *pPacket +- trans := packet.TransportLayer() ++func packetFilter(portCache *portCache, packet gopacket.Packet, whitelistDnsServers *v2router.GeoIPMatcher) (m *dnsmessage.Message, pSAddr, pSPort, pDAddr, pDPort *gopacket.Endpoint) { ++ //跳过非网络层的包 ++ if packet.NetworkLayer() == nil { ++ return ++ } + //跳过非传输层的包 ++ trans := packet.TransportLayer() + if trans == nil { + return + } +@@ -180,7 +183,7 @@ func packetFilter(portCache *portCache, + } + + func (interfaceHandle *handle) handlePacket(packet gopacket.Packet, ifname string, whitelistDnsServers *v2router.GeoIPMatcher, whitelistDomains *strmatcher.MatcherGroup) { +- m, sAddr, sPort, dAddr, dPort := packetFilter(interfaceHandle.portCache, &packet, whitelistDnsServers) ++ m, sAddr, sPort, dAddr, dPort := packetFilter(interfaceHandle.portCache, packet, whitelistDnsServers) + if m == nil { + return + } +--- a/core/specialMode/infra/supervisor.go ++++ b/core/specialMode/infra/supervisor.go +@@ -9,7 +9,6 @@ import ( + v2router "github.com/v2rayA/v2ray-lib/router" + "github.com/v2rayA/v2rayA/pkg/util/log" + "sync" +- "time" + ) + + type DnsSupervisor struct { +@@ -70,7 +69,7 @@ func (d *DnsSupervisor) DeleteHandles(if + } + close(d.handles[ifname].done) + delete(d.handles, ifname) +- log.Trace("DnsSupervisor:%v closed", ifname) ++ log.Trace("DnsSupervisor:%v deleted", ifname) + return + } + +@@ -81,28 +80,24 @@ func (d *DnsSupervisor) Run(ifname strin + d.inner.Lock() + handle, ok := d.handles[ifname] + if !ok { ++ d.inner.Unlock() + return fmt.Errorf("Run: %v not exsits", ifname) + } + if handle.running { ++ d.inner.Unlock() + return fmt.Errorf("Run: %v is running", ifname) + } + handle.running = true + log.Trace("[DnsSupervisor] " + ifname + ": running") +- pkgsrc := gopacket.NewPacketSource(handle, layers.LayerTypeEthernet) ++ // we only decode UDP packets ++ pkgsrc := gopacket.NewPacketSource(handle, layers.LayerTypeDNS) + pkgsrc.NoCopy = true ++ //pkgsrc.Lazy = true + d.inner.Unlock() + packets := pkgsrc.Packets() + go func() { +- for { +- //心跳包,防止内存泄漏 +- packets <- gopacket.NewPacket(nil, layers.LinkTypeEthernet, gopacket.DecodeOptions{}) +- select { +- case <-handle.done: +- return +- default: +- time.Sleep(2 * time.Second) +- } +- } ++ <-handle.done ++ packets <- gopacket.NewPacket(nil, layers.LinkTypeEthernet, pkgsrc.DecodeOptions) + }() + out: + for packet := range packets { +@@ -113,5 +108,6 @@ out: + } + go handle.handlePacket(packet, ifname, whitelistDnsServers, whitelistDomains) + } ++ log.Trace("DnsSupervisor:%v closed", ifname) + return + } diff --git a/v2raya/patches/016-fix-unexpected-exit-does-not-apply-stop-steps.patch b/v2raya/patches/016-fix-unexpected-exit-does-not-apply-stop-steps.patch new file mode 100644 index 000000000..a945dbdeb --- /dev/null +++ b/v2raya/patches/016-fix-unexpected-exit-does-not-apply-stop-steps.patch @@ -0,0 +1,52 @@ +From 153b72ed623876ad73b731c2ec2344e9057d3c35 Mon Sep 17 00:00:00 2001 +From: mzz2017 +Date: Wed, 21 Sep 2022 16:50:24 +0800 +Subject: [PATCH] fix: unexpected exit does not apply stop steps + +--- + service/core/v2ray/process.go | 4 ++-- + service/core/v2ray/processManager.go | 8 +++----- + 2 files changed, 5 insertions(+), 7 deletions(-) + +--- a/core/v2ray/process.go ++++ b/core/v2ray/process.go +@@ -35,7 +35,7 @@ type Process struct { + tag2WhichIndex map[string]int + } + +-func NewProcess(tmpl *Template, prestart func() error, poststart func() error) (process *Process, err error) { ++func NewProcess(tmpl *Template, prestart func() error, poststart func() error, stopfunc func(p *Process)) (process *Process, err error) { + process = &Process{ + template: tmpl, + } +@@ -111,7 +111,7 @@ func NewProcess(tmpl *Template, prestart + // canceled by v2rayA + return + } +- defer ProcessManager.Stop(false) ++ defer stopfunc(process) + var t []string + if p != nil { + if p.Success() { +--- a/core/v2ray/processManager.go ++++ b/core/v2ray/processManager.go +@@ -245,16 +245,14 @@ func (m *CoreProcessManager) Start(t *Te + return m.beforeStart(t) + }, func() error { + return m.afterStart(t) ++ }, func(p *Process) { ++ m.p = p ++ ProcessManager.Stop(false) + }) + if err != nil { + return err + } + m.p = process +- defer func() { +- if err != nil { +- m.stop(true) +- } +- }() + + configure.SetRunning(true) + return nil diff --git a/v2raya/patches/017-optimize-reduce-disk-writes.patch b/v2raya/patches/017-optimize-reduce-disk-writes.patch new file mode 100644 index 000000000..5437570c9 --- /dev/null +++ b/v2raya/patches/017-optimize-reduce-disk-writes.patch @@ -0,0 +1,336 @@ +From 00366b224b2e28861b80f677e8aa604c5d08dae3 Mon Sep 17 00:00:00 2001 +From: Kelo +Date: Sat, 29 Oct 2022 16:27:26 +0800 +Subject: [PATCH] optimize: reduce disk writes + +--- + service/db/boltdb.go | 43 +++++++++++++++++++++++++++++++---- + service/db/listOp.go | 48 +++++++++++++++++++++------------------ + service/db/plainOp.go | 52 ++++++++++++++++++++++++------------------- + service/db/setOp.go | 20 +++++++++-------- + 4 files changed, 105 insertions(+), 58 deletions(-) + +--- a/db/boltdb.go ++++ b/db/boltdb.go +@@ -1,13 +1,14 @@ + package db + + import ( +- "go.etcd.io/bbolt" +- "github.com/v2rayA/v2rayA/conf" +- "github.com/v2rayA/v2rayA/pkg/util/copyfile" +- "github.com/v2rayA/v2rayA/pkg/util/log" + "os" + "path/filepath" + "sync" ++ ++ "github.com/v2rayA/v2rayA/conf" ++ "github.com/v2rayA/v2rayA/pkg/util/copyfile" ++ "github.com/v2rayA/v2rayA/pkg/util/log" ++ "go.etcd.io/bbolt" + ) + + var once sync.Once +@@ -46,3 +47,37 @@ func DB() *bbolt.DB { + once.Do(initDB) + return db + } ++ ++// The function should return a dirty flag. ++// If the dirty flag is true and there is no error then the transaction is commited. ++// Otherwise, the transaction is rolled back. ++func Transaction(db *bbolt.DB, fn func(*bbolt.Tx) (bool, error)) error { ++ tx, err := db.Begin(true) ++ if err != nil { ++ return err ++ } ++ defer tx.Rollback() ++ dirty, err := fn(tx) ++ if err != nil { ++ _ = tx.Rollback() ++ return err ++ } ++ if !dirty { ++ return nil ++ } ++ return tx.Commit() ++} ++ ++// If the bucket does not exist, the dirty flag is setted ++func CreateBucketIfNotExists(tx *bbolt.Tx, name []byte, dirty *bool) (*bbolt.Bucket, error) { ++ bkt := tx.Bucket(name) ++ if bkt != nil { ++ return bkt, nil ++ } ++ bkt, err := tx.CreateBucket(name) ++ if err != nil { ++ return nil, err ++ } ++ *dirty = true ++ return bkt, nil ++} +--- a/db/listOp.go ++++ b/db/listOp.go +@@ -2,13 +2,14 @@ package db + + import ( + "fmt" +- "go.etcd.io/bbolt" +- jsoniter "github.com/json-iterator/go" +- "github.com/tidwall/gjson" +- "github.com/tidwall/sjson" + "reflect" + "sort" + "strconv" ++ ++ jsoniter "github.com/json-iterator/go" ++ "github.com/tidwall/gjson" ++ "github.com/tidwall/sjson" ++ "go.etcd.io/bbolt" + ) + + func ListSet(bucket string, key string, index int, val interface{}) (err error) { +@@ -31,20 +32,21 @@ func ListSet(bucket string, key string, + } + + func ListGet(bucket string, key string, index int) (b []byte, err error) { +- err = DB().Update(func(tx *bbolt.Tx) error { +- if bkt, err := tx.CreateBucketIfNotExists([]byte(bucket)); err != nil { +- return err ++ err = Transaction(DB(), func(tx *bbolt.Tx) (bool, error) { ++ dirty := false ++ if bkt, err := CreateBucketIfNotExists(tx, []byte(bucket), &dirty); err != nil { ++ return dirty, err + } else { + v := bkt.Get([]byte(key)) + if v == nil { +- return fmt.Errorf("ListGet: can't get element from an empty list") ++ return dirty, fmt.Errorf("ListGet: can't get element from an empty list") + } + r := gjson.GetBytes(v, strconv.Itoa(index)) + if r.Exists() { + b = []byte(r.Raw) +- return nil ++ return dirty, nil + } else { +- return fmt.Errorf("ListGet: no such element") ++ return dirty, fmt.Errorf("ListGet: no such element") + } + } + }) +@@ -79,24 +81,25 @@ func ListAppend(bucket string, key strin + } + + func ListGetAll(bucket string, key string) (list [][]byte, err error) { +- err = DB().Update(func(tx *bbolt.Tx) error { +- if bkt, err := tx.CreateBucketIfNotExists([]byte(bucket)); err != nil { +- return err ++ err = Transaction(DB(), func(tx *bbolt.Tx) (bool, error) { ++ dirty := false ++ if bkt, err := CreateBucketIfNotExists(tx, []byte(bucket), &dirty); err != nil { ++ return dirty, err + } else { + b := bkt.Get([]byte(key)) + if b == nil { +- return nil ++ return dirty, nil + } + parsed := gjson.ParseBytes(b) + if !parsed.IsArray() { +- return fmt.Errorf("ListGetAll: is not array") ++ return dirty, fmt.Errorf("ListGetAll: is not array") + } + results := parsed.Array() + for _, r := range results { + list = append(list, []byte(r.Raw)) + } + } +- return nil ++ return dirty, nil + }) + return list, err + } +@@ -143,21 +146,22 @@ func ListRemove(bucket, key string, inde + } + + func ListLen(bucket string, key string) (length int, err error) { +- err = DB().Update(func(tx *bbolt.Tx) error { +- if bkt, err := tx.CreateBucketIfNotExists([]byte(bucket)); err != nil { +- return err ++ err = Transaction(DB(), func(tx *bbolt.Tx) (bool, error) { ++ dirty := false ++ if bkt, err := CreateBucketIfNotExists(tx, []byte(bucket), &dirty); err != nil { ++ return dirty, err + } else { + b := bkt.Get([]byte(key)) + if b == nil { +- return nil ++ return dirty, nil + } + parsed := gjson.ParseBytes(b) + if !parsed.IsArray() { +- return fmt.Errorf("ListLen: is not array") ++ return dirty, fmt.Errorf("ListLen: is not array") + } + length = len(parsed.Array()) + } +- return nil ++ return dirty, nil + }) + return length, err + } +--- a/db/plainOp.go ++++ b/db/plainOp.go +@@ -2,50 +2,54 @@ package db + + import ( + "fmt" +- "go.etcd.io/bbolt" ++ + jsoniter "github.com/json-iterator/go" + "github.com/v2rayA/v2rayA/common" + "github.com/v2rayA/v2rayA/pkg/util/log" ++ "go.etcd.io/bbolt" + ) + + func Get(bucket string, key string, val interface{}) (err error) { +- return DB().Update(func(tx *bbolt.Tx) error { +- if bkt, err := tx.CreateBucketIfNotExists([]byte(bucket)); err != nil { +- return err ++ return Transaction(DB(), func(tx *bbolt.Tx) (bool, error) { ++ dirty := false ++ if bkt, err := CreateBucketIfNotExists(tx, []byte(bucket), &dirty); err != nil { ++ return dirty, err + } else { + if v := bkt.Get([]byte(key)); v == nil { +- return fmt.Errorf("Get: key is not found") ++ return dirty, fmt.Errorf("Get: key is not found") + } else { +- return jsoniter.Unmarshal(v, val) ++ return dirty, jsoniter.Unmarshal(v, val) + } + } + }) + } + + func GetRaw(bucket string, key string) (b []byte, err error) { +- err = DB().Update(func(tx *bbolt.Tx) error { +- if bkt, err := tx.CreateBucketIfNotExists([]byte(bucket)); err != nil { +- return err ++ err = Transaction(DB(), func(tx *bbolt.Tx) (bool, error) { ++ dirty := false ++ if bkt, err := CreateBucketIfNotExists(tx, []byte(bucket), &dirty); err != nil { ++ return dirty, err + } else { + v := bkt.Get([]byte(key)) + if v == nil { +- return fmt.Errorf("GetRaw: key is not found") ++ return dirty, fmt.Errorf("GetRaw: key is not found") + } + b = common.BytesCopy(v) +- return nil ++ return dirty, nil + } + }) + return b, err + } + + func Exists(bucket string, key string) (exists bool) { +- if err := DB().Update(func(tx *bbolt.Tx) error { +- if bkt, err := tx.CreateBucketIfNotExists([]byte(bucket)); err != nil { +- return err ++ if err := Transaction(DB(), func(tx *bbolt.Tx) (bool, error) { ++ dirty := false ++ if bkt, err := CreateBucketIfNotExists(tx, []byte(bucket), &dirty); err != nil { ++ return dirty, err + } else { + v := bkt.Get([]byte(key)) + exists = v != nil +- return nil ++ return dirty, nil + } + }); err != nil { + log.Warn("%v", err) +@@ -55,23 +59,25 @@ func Exists(bucket string, key string) ( + } + + func GetBucketLen(bucket string) (length int, err error) { +- err = DB().Update(func(tx *bbolt.Tx) error { +- if bkt, err := tx.CreateBucketIfNotExists([]byte(bucket)); err != nil { +- return err ++ err = Transaction(DB(), func(tx *bbolt.Tx) (bool, error) { ++ dirty := false ++ if bkt, err := CreateBucketIfNotExists(tx, []byte(bucket), &dirty); err != nil { ++ return dirty, err + } else { + length = bkt.Stats().KeyN + } +- return nil ++ return dirty, nil + }) + return length, err + } + + func GetBucketKeys(bucket string) (keys []string, err error) { +- err = DB().Update(func(tx *bbolt.Tx) error { +- if bkt, err := tx.CreateBucketIfNotExists([]byte(bucket)); err != nil { +- return err ++ err = Transaction(DB(), func(tx *bbolt.Tx) (bool, error) { ++ dirty := false ++ if bkt, err := CreateBucketIfNotExists(tx, []byte(bucket), &dirty); err != nil { ++ return dirty, err + } else { +- return bkt.ForEach(func(k, v []byte) error { ++ return dirty, bkt.ForEach(func(k, v []byte) error { + keys = append(keys, string(k)) + return nil + }) +--- a/db/setOp.go ++++ b/db/setOp.go +@@ -4,8 +4,9 @@ import ( + "bytes" + "crypto/sha256" + "encoding/gob" +- "go.etcd.io/bbolt" ++ + "github.com/v2rayA/v2rayA/common" ++ "go.etcd.io/bbolt" + ) + + type set map[[32]byte]interface{} +@@ -28,26 +29,27 @@ func toSha256(val interface{}) (hash [32 + } + + func setOp(bucket string, key string, f func(m set) (readonly bool, err error)) (err error) { +- return DB().Update(func(tx *bbolt.Tx) error { +- if bkt, err := tx.CreateBucketIfNotExists([]byte(bucket)); err != nil { +- return err ++ return Transaction(DB(), func(tx *bbolt.Tx) (bool, error) { ++ dirty := false ++ if bkt, err := CreateBucketIfNotExists(tx, []byte(bucket), &dirty); err != nil { ++ return dirty, err + } else { + var m set + v := bkt.Get([]byte(key)) + if v == nil { + m = make(set) + } else if err := gob.NewDecoder(bytes.NewReader(v)).Decode(&m); err != nil { +- return err ++ return dirty, err + } + if readonly, err := f(m); err != nil { +- return err ++ return dirty, err + } else if readonly { +- return nil ++ return dirty, nil + } + if b, err := common.ToBytes(m); err != nil { +- return err ++ return dirty, err + } else { +- return bkt.Put([]byte(key), b) ++ return true, bkt.Put([]byte(key), b) + } + } + }) diff --git a/v2raya/patches/018-fix-do-not-rollback-closed-transaction.patch b/v2raya/patches/018-fix-do-not-rollback-closed-transaction.patch new file mode 100644 index 000000000..b9815f459 --- /dev/null +++ b/v2raya/patches/018-fix-do-not-rollback-closed-transaction.patch @@ -0,0 +1,27 @@ +From 451912074ba1ba4000c66874876bc0a6b64cb5da Mon Sep 17 00:00:00 2001 +From: Kelo +Date: Sun, 30 Oct 2022 16:49:22 +0800 +Subject: [PATCH] fix: do not rollback closed transaction + +--- + service/db/boltdb.go | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/db/boltdb.go ++++ b/db/boltdb.go +@@ -56,14 +56,13 @@ func Transaction(db *bbolt.DB, fn func(* + if err != nil { + return err + } +- defer tx.Rollback() + dirty, err := fn(tx) + if err != nil { + _ = tx.Rollback() + return err + } + if !dirty { +- return nil ++ return tx.Rollback() + } + return tx.Commit() + } diff --git a/v2raya/patches/100-compat-v5.patch b/v2raya/patches/100-compat-v5.patch new file mode 100644 index 000000000..ef358c944 --- /dev/null +++ b/v2raya/patches/100-compat-v5.patch @@ -0,0 +1,21 @@ +--- a/core/v2ray/process.go ++++ b/core/v2ray/process.go +@@ -226,6 +226,7 @@ func StartCoreProcess(ctx context.Contex + dir := path.Dir(v2rayBinPath) + var arguments = []string{ + v2rayBinPath, ++ "run", + "--config=" + asset.GetV2rayConfigPath(), + } + if confdir := asset.GetV2rayConfigDirPath(); confdir != "" { +--- a/core/v2ray/where/where.go ++++ b/core/v2ray/where/where.go +@@ -41,7 +41,7 @@ func GetV2rayServiceVersion() (variant V + if err != nil || len(v2rayPath) <= 0 { + return Unknown, "", fmt.Errorf("cannot find v2ray executable binary") + } +- out, err := exec.Command(v2rayPath, "-version").Output() ++ out, err := exec.Command(v2rayPath, "version").Output() + var fields []string + if fields = strings.Fields(strings.TrimSpace(string(out))); len(fields) < 2 { + return Unknown, "", fmt.Errorf("cannot parse version of v2ray")