Quellcode durchsuchen

v2raya: sync upstream

Beginner-Go vor 1 Jahr
Ursprung
Commit
bbdf63e017

+ 9 - 11
v2raya/Makefile

@@ -5,12 +5,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=v2rayA
-PKG_VERSION:=1.5.9.1698.1
+PKG_VERSION:=2.2.4.6
 PKG_RELEASE:=2
 
 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_HASH:=22285b2fdf321d68993b38ad738f4af210920757d7944691a78e151abd99cb3a
 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)/service
 
 PKG_LICENSE:=AGPL-3.0-only
@@ -23,7 +23,9 @@ PKG_USE_MIPS16:=0
 PKG_BUILD_FLAGS:=no-mips16
 
 GO_PKG:=github.com/v2rayA/v2rayA
-GO_PKG_LDFLAGS_X:=$(GO_PKG)/conf.Version=$(PKG_VERSION)
+GO_PKG_LDFLAGS_X:= \
+	$(GO_PKG)/conf.Version=$(PKG_VERSION) \
+	$(GO_PKG)/core/iptables.TproxyNotSkipBr=true
 
 include $(INCLUDE_DIR)/package.mk
 include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk
@@ -38,11 +40,7 @@ define Package/v2raya
   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 \
+    +kmod-nft-tproxy \
     +xray-core
   URL:=https://v2raya.org
 endef
@@ -59,10 +57,10 @@ 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)
+	URL:=https://github.com/v2rayA/v2rayA/releases/download/v$(PKG_VERSION)/
+	URL_FILE:=web.tar.gz
 	FILE:=$(WEB_FILE)
-	HASH:=149097a42c3e5fa6f5c3cd46d1bf7ec4546e79ad37c1446b759539e700bd75e2
+	HASH:=09109442abac13801b7b82433fccbb769657b1d292ac4820af179c297e845135
 endef
 
 define Build/Prepare

+ 4 - 10
v2raya/files/v2raya.config

@@ -5,19 +5,17 @@ config v2raya 'config'
 	# 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'
 
+	# Experimental feature. Make sure you have installed nftables.
+	# Optional values: auto, on, off.
+	option nftables_support 'auto'
+
 	# Optional values: trace, debug, info, warn or error
 	option log_level 'info'
 
-	# 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'
 
@@ -44,7 +42,3 @@ config v2raya 'config'
 	# 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 ''
-

+ 4 - 3
v2raya/files/v2raya.init

@@ -40,18 +40,19 @@ start_service() {
 	procd_set_param command "$PROG"
 	procd_set_param env XDG_DATA_HOME="/usr/share"
 
+	append_env "config" "/etc/v2raya"
+	append_env "log_file" "/var/log/v2raya/v2raya.log"
+
 	append_env_arg "config" "address" "0.0.0.0:2017"
-	append_env_arg "config" "config" "/etc/v2raya"
 	append_env_arg "config" "ipv6_support" "auto"
+	append_env_arg "config" "nftables_support" "auto"
 	append_env_arg "config" "log_level" "info"
-	append_env_arg "config" "log_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"
 

+ 0 - 38
v2raya/patches/013-fix-we-should-skip-interface-ppp-to-avoid-to-break-net.patch

@@ -1,38 +0,0 @@
-From ca6a05273284daa04856a840e64f3936f700b7c3 Mon Sep 17 00:00:00 2001
-From: mzz2017 <[email protected]>
-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 := 5
-+	pos := 7
- 	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 += `

+ 0 - 105
v2raya/patches/014-fix-seed-cannot-be-read-from-vless-sharing-link-and-add-m.patch

@@ -1,105 +0,0 @@
-From 5db722b22b39642280572a62b149d4e1efa21ce3 Mon Sep 17 00:00:00 2001
-From: mzz2017 <[email protected]>
-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

+ 0 - 100
v2raya/patches/015-fix-a-problem-that-supervisor-cannot-exit-normally.patch

@@ -1,100 +0,0 @@
-From 3f78422f81f3abc2668fc3938b31d213bfe4dfff Mon Sep 17 00:00:00 2001
-From: mzz2017 <[email protected]>
-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
- }

+ 0 - 52
v2raya/patches/016-fix-unexpected-exit-does-not-apply-stop-steps.patch

@@ -1,52 +0,0 @@
-From 153b72ed623876ad73b731c2ec2344e9057d3c35 Mon Sep 17 00:00:00 2001
-From: mzz2017 <[email protected]>
-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

+ 0 - 336
v2raya/patches/017-optimize-reduce-disk-writes.patch

@@ -1,336 +0,0 @@
-From 00366b224b2e28861b80f677e8aa604c5d08dae3 Mon Sep 17 00:00:00 2001
-From: Kelo <[email protected]>
-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)
- 			}
- 		}
- 	})

+ 0 - 27
v2raya/patches/018-fix-do-not-rollback-closed-transaction.patch

@@ -1,27 +0,0 @@
-From 451912074ba1ba4000c66874876bc0a6b64cb5da Mon Sep 17 00:00:00 2001
-From: Kelo <[email protected]>
-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()
- }

+ 0 - 21
v2raya/patches/100-compat-v5.patch

@@ -1,21 +0,0 @@
---- 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")