update 2023-01-26 15:12:50

This commit is contained in:
github-actions[bot] 2023-01-26 15:12:50 +08:00
parent fdf46e9e5e
commit ff8b07f679
26 changed files with 1533 additions and 4 deletions

47
cdnspeedtest/Makefile Normal file
View File

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

68
filebrowser/Makefile Normal file
View File

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

View File

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

View File

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

85
homebox/Makefile Normal file
View File

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

View File

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

View File

@ -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 <em>empty</em> 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();
}
});

View File

@ -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 <em>empty</em> 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 ""

1
luci-app-msd_lite/po/zh-cn Symbolic link
View File

@ -0,0 +1 @@
zh_Hans

View File

@ -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 <em>empty</em> to auto detect."
msgstr "保留为 0 或<em>留空</em>以自动检测。"
#: 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 "工作线程"

View File

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

View File

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

View File

@ -12,22 +12,22 @@ PKG_MAINTAINER:=Tianling Shen <cnsztl@immortalwrt.org>
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

89
v2raya/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:=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 <cnsztl@immortalwrt.org>
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))

View File

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

74
v2raya/files/v2raya.init Executable file
View File

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

View File

@ -0,0 +1,46 @@
From 78336e55a31db578c139a5bb472aa0fc219c169d Mon Sep 17 00:00:00 2001
From: Xiaoxu Guo <ftiasch0@gmail.com>
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

View File

@ -0,0 +1,37 @@
From 0db405f50fd652d494f2066fc5e47c41666c96db Mon Sep 17 00:00:00 2001
From: Xiaoxu Guo <ftiasch0@gmail.com>
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

View File

@ -0,0 +1,38 @@
From 4a87a6fc9a17939cc0fc54058b2128b1f688045a Mon Sep 17 00:00:00 2001
From: Xiaoxu Guo <ftiasch0@gmail.com>
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
`

View File

@ -0,0 +1,38 @@
From ca6a05273284daa04856a840e64f3936f700b7c3 Mon Sep 17 00:00:00 2001
From: mzz2017 <mzz@tuta.io>
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 += `

View File

@ -0,0 +1,105 @@
From 5db722b22b39642280572a62b149d4e1efa21ce3 Mon Sep 17 00:00:00 2001
From: mzz2017 <mzz@tuta.io>
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

View File

@ -0,0 +1,100 @@
From 3f78422f81f3abc2668fc3938b31d213bfe4dfff Mon Sep 17 00:00:00 2001
From: mzz2017 <mzz@tuta.io>
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
}

View File

@ -0,0 +1,52 @@
From 153b72ed623876ad73b731c2ec2344e9057d3c35 Mon Sep 17 00:00:00 2001
From: mzz2017 <mzz@tuta.io>
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

View File

@ -0,0 +1,336 @@
From 00366b224b2e28861b80f677e8aa604c5d08dae3 Mon Sep 17 00:00:00 2001
From: Kelo <meetkelo@outlook.com>
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)
}
}
})

View File

@ -0,0 +1,27 @@
From 451912074ba1ba4000c66874876bc0a6b64cb5da Mon Sep 17 00:00:00 2001
From: Kelo <meetkelo@outlook.com>
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()
}

View File

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