Community maintained packages for ImmortalWrt.
Revision | fe8cda5d6e063b430adad7216194595d18cec9fe (tree) |
---|---|
Time | 2023-03-19 00:13:34 |
Author | Tianling Shen <cnsztl@immo...> |
Commiter | Tianling Shen |
v2raya: Update to 2.0.2
- Added TproxyNotSkipBr flag for OpenWrt.
- Removed all upstreamed patches.
- Refreshed nftables patch.
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
@@ -5,12 +5,12 @@ | ||
5 | 5 | include $(TOPDIR)/rules.mk |
6 | 6 | |
7 | 7 | PKG_NAME:=v2rayA |
8 | -PKG_VERSION:=1.5.9.1698.1 | |
9 | -PKG_RELEASE:=4 | |
8 | +PKG_VERSION:=2.0.2 | |
9 | +PKG_RELEASE:=1 | |
10 | 10 | |
11 | 11 | PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz |
12 | 12 | PKG_SOURCE_URL:=https://codeload.github.com/v2rayA/v2rayA/tar.gz/v$(PKG_VERSION)? |
13 | -PKG_HASH:=247a357230c616bf48309c61d119686e4ad56939c05afef584c45051e9dc6220 | |
13 | +PKG_HASH:=5bb02d178cdc95de1facdd214392d753be128bef522ae7654ebdbc880b874f37 | |
14 | 14 | PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)/service |
15 | 15 | |
16 | 16 | PKG_LICENSE:=AGPL-3.0-only |
@@ -22,7 +22,9 @@ PKG_BUILD_PARALLEL:=1 | ||
22 | 22 | PKG_USE_MIPS16:=0 |
23 | 23 | |
24 | 24 | GO_PKG:=github.com/v2rayA/v2rayA |
25 | -GO_PKG_LDFLAGS_X:=$(GO_PKG)/conf.Version=$(PKG_VERSION) | |
25 | +GO_PKG_LDFLAGS_X:= \ | |
26 | + $(GO_PKG)/conf.Version=$(PKG_VERSION) \ | |
27 | + $(GO_PKG)/core/iptables.TproxyNotSkipBr=true | |
26 | 28 | |
27 | 29 | include $(INCLUDE_DIR)/package.mk |
28 | 30 | include ../../lang/golang/golang-package.mk |
@@ -57,7 +59,7 @@ define Download/v2raya-web | ||
57 | 59 | URL:=https://codeload.github.com/v2rayA/v2raya-web/tar.gz/v$(PKG_VERSION)? |
58 | 60 | URL_FILE:=$(WEB_FILE) |
59 | 61 | FILE:=$(WEB_FILE) |
60 | - HASH:=149097a42c3e5fa6f5c3cd46d1bf7ec4546e79ad37c1446b759539e700bd75e2 | |
62 | + HASH:=830e201d1098d7e8ec8b61c6b4d192dda34dd9f745c8b937c7335306a498bf97 | |
61 | 63 | endef |
62 | 64 | |
63 | 65 | define Build/Prepare |
@@ -1,38 +0,0 @@ | ||
1 | -From ca6a05273284daa04856a840e64f3936f700b7c3 Mon Sep 17 00:00:00 2001 | |
2 | -From: mzz2017 <mzz@tuta.io> | |
3 | -Date: Fri, 16 Sep 2022 15:13:11 +0800 | |
4 | -Subject: [PATCH] fix: we should skip interface ppp+ to avoid to break net | |
5 | - | |
6 | ---- | |
7 | - service/core/iptables/tproxy.go | 6 +++++- | |
8 | - 1 file changed, 5 insertions(+), 1 deletion(-) | |
9 | - | |
10 | ---- a/core/iptables/tproxy.go | |
11 | -+++ b/core/iptables/tproxy.go | |
12 | -@@ -16,7 +16,7 @@ var Tproxy tproxy | |
13 | - func (t *tproxy) AddIPWhitelist(cidr string) { | |
14 | - // avoid duplication | |
15 | - t.RemoveIPWhitelist(cidr) | |
16 | -- pos := 5 | |
17 | -+ pos := 7 | |
18 | - if configure.GetSettingNotNil().AntiPollution != configure.AntipollutionClosed { | |
19 | - pos += 3 | |
20 | - } | |
21 | -@@ -67,6 +67,8 @@ iptables -w 2 -t mangle -A TP_RULE -j CO | |
22 | - iptables -w 2 -t mangle -A TP_RULE -m mark --mark 0x40/0xc0 -j RETURN | |
23 | - iptables -w 2 -t mangle -A TP_RULE -i docker+ -j RETURN | |
24 | - iptables -w 2 -t mangle -A TP_RULE -i veth+ -j RETURN | |
25 | -+iptables -w 2 -t mangle -A TP_RULE -i ppp+ -j RETURN | |
26 | -+iptables -w 2 -t mangle -A TP_RULE -i dn42-+ -j RETURN | |
27 | - ` | |
28 | - if configure.GetSettingNotNil().AntiPollution != configure.AntipollutionClosed { | |
29 | - commands += ` | |
30 | -@@ -125,6 +127,8 @@ ip6tables -w 2 -t mangle -A TP_RULE -j C | |
31 | - ip6tables -w 2 -t mangle -A TP_RULE -m mark --mark 0x40/0xc0 -j RETURN | |
32 | - ip6tables -w 2 -t mangle -A TP_RULE -i docker+ -j RETURN | |
33 | - ip6tables -w 2 -t mangle -A TP_RULE -i veth+ -j RETURN | |
34 | -+ip6tables -w 2 -t mangle -A TP_RULE -i ppp+ -j RETURN | |
35 | -+ip6tables -w 2 -t mangle -A TP_RULE -i dn42-+ -j RETURN | |
36 | - ` | |
37 | - if configure.GetSettingNotNil().AntiPollution != configure.AntipollutionClosed { | |
38 | - commands += ` |
@@ -1,105 +0,0 @@ | ||
1 | -From 5db722b22b39642280572a62b149d4e1efa21ce3 Mon Sep 17 00:00:00 2001 | |
2 | -From: mzz2017 <mzz@tuta.io> | |
3 | -Date: Mon, 8 Aug 2022 22:30:36 +0800 | |
4 | -Subject: [PATCH] fix: seed cannot be read from vless sharing-link and add | |
5 | - missing sni field. #616 | |
6 | - | |
7 | ---- | |
8 | - service/core/serverObj/v2ray.go | 24 +++++++++++------------- | |
9 | - 1 file changed, 11 insertions(+), 13 deletions(-) | |
10 | - | |
11 | ---- a/core/serverObj/v2ray.go | |
12 | -+++ b/core/serverObj/v2ray.go | |
13 | -@@ -12,7 +12,6 @@ import ( | |
14 | - "time" | |
15 | - | |
16 | - jsoniter "github.com/json-iterator/go" | |
17 | -- "github.com/tidwall/gjson" | |
18 | - "github.com/v2rayA/v2rayA/common" | |
19 | - "github.com/v2rayA/v2rayA/core/coreObj" | |
20 | - "github.com/v2rayA/v2rayA/core/v2ray/service" | |
21 | -@@ -39,6 +38,7 @@ type V2Ray struct { | |
22 | - Net string `json:"net"` | |
23 | - Type string `json:"type"` | |
24 | - Host string `json:"host"` | |
25 | -+ SNI string `json:"sni"` | |
26 | - Path string `json:"path"` | |
27 | - TLS string `json:"tls"` | |
28 | - Flow string `json:"flow,omitempty"` | |
29 | -@@ -69,7 +69,8 @@ func ParseVlessURL(vless string) (data * | |
30 | - ID: u.User.String(), | |
31 | - Net: u.Query().Get("type"), | |
32 | - Type: u.Query().Get("headerType"), | |
33 | -- Host: u.Query().Get("sni"), | |
34 | -+ Host: u.Query().Get("host"), | |
35 | -+ SNI: u.Query().Get("sni"), | |
36 | - Path: u.Query().Get("path"), | |
37 | - TLS: u.Query().Get("security"), | |
38 | - Flow: u.Query().Get("flow"), | |
39 | -@@ -86,16 +87,13 @@ func ParseVlessURL(vless string) (data * | |
40 | - if data.Type == "" { | |
41 | - data.Type = "none" | |
42 | - } | |
43 | -- if data.Host == "" { | |
44 | -- data.Host = u.Query().Get("host") | |
45 | -- } | |
46 | - if data.TLS == "" { | |
47 | - data.TLS = "none" | |
48 | - } | |
49 | - if data.Flow == "" { | |
50 | - data.Flow = "xtls-rprx-direct" | |
51 | - } | |
52 | -- if data.Type == "mkcp" || data.Type == "kcp" { | |
53 | -+ if data.Net == "mkcp" || data.Net == "kcp" { | |
54 | - data.Path = u.Query().Get("seed") | |
55 | - } | |
56 | - return data, nil | |
57 | -@@ -145,6 +143,7 @@ func ParseVmessURL(vmess string) (data * | |
58 | - if aid == "" { | |
59 | - aid = q.Get("aid") | |
60 | - } | |
61 | -+ sni := q.Get("sni") | |
62 | - info = V2Ray{ | |
63 | - ID: subMatch[1], | |
64 | - Add: subMatch[2], | |
65 | -@@ -152,6 +151,7 @@ func ParseVmessURL(vmess string) (data * | |
66 | - Ps: ps, | |
67 | - Host: obfsParam, | |
68 | - Path: path, | |
69 | -+ SNI: sni, | |
70 | - Net: obfs, | |
71 | - Aid: aid, | |
72 | - TLS: map[string]string{"1": "tls"}[q.Get("tls")], | |
73 | -@@ -165,12 +165,6 @@ func ParseVmessURL(vmess string) (data * | |
74 | - if err != nil { | |
75 | - return | |
76 | - } | |
77 | -- if info.Host == "" { | |
78 | -- sni := gjson.Get(raw, "sni") | |
79 | -- if sni.Exists() { | |
80 | -- info.Host = sni.String() | |
81 | -- } | |
82 | -- } | |
83 | - } | |
84 | - // correct the wrong vmess as much as possible | |
85 | - if strings.HasPrefix(info.Host, "/") && info.Path == "" { | |
86 | -@@ -328,7 +322,9 @@ func (v *V2Ray) Configuration(info Prior | |
87 | - core.StreamSettings.TLSSettings.AllowInsecure = true | |
88 | - } | |
89 | - // SNI | |
90 | -- if v.Host != "" { | |
91 | -+ if v.SNI != "" { | |
92 | -+ core.StreamSettings.TLSSettings.ServerName = v.SNI | |
93 | -+ } else if v.Host != "" { | |
94 | - core.StreamSettings.TLSSettings.ServerName = v.Host | |
95 | - } | |
96 | - // Alpn | |
97 | -@@ -345,6 +341,8 @@ func (v *V2Ray) Configuration(info Prior | |
98 | - // SNI | |
99 | - if v.Host != "" { | |
100 | - core.StreamSettings.XTLSSettings.ServerName = v.Host | |
101 | -+ } else if v.Host != "" { | |
102 | -+ core.StreamSettings.TLSSettings.ServerName = v.Host | |
103 | - } | |
104 | - if v.AllowInsecure { | |
105 | - core.StreamSettings.XTLSSettings.AllowInsecure = true |
@@ -1,100 +0,0 @@ | ||
1 | -From 3f78422f81f3abc2668fc3938b31d213bfe4dfff Mon Sep 17 00:00:00 2001 | |
2 | -From: mzz2017 <mzz@tuta.io> | |
3 | -Date: Sun, 28 Aug 2022 17:54:36 +0800 | |
4 | -Subject: [PATCH] fix: a problem that supervisor cannot exit normally | |
5 | - | |
6 | ---- | |
7 | - service/core/specialMode/infra/handle.go | 11 ++++++---- | |
8 | - service/core/specialMode/infra/supervisor.go | 22 ++++++++------------ | |
9 | - 2 files changed, 16 insertions(+), 17 deletions(-) | |
10 | - | |
11 | ---- a/core/specialMode/infra/handle.go | |
12 | -+++ b/core/specialMode/infra/handle.go | |
13 | -@@ -127,10 +127,13 @@ func (interfaceHandle *handle) handleRec | |
14 | - return results, msg | |
15 | - } | |
16 | - | |
17 | --func packetFilter(portCache *portCache, pPacket *gopacket.Packet, whitelistDnsServers *v2router.GeoIPMatcher) (m *dnsmessage.Message, pSAddr, pSPort, pDAddr, pDPort *gopacket.Endpoint) { | |
18 | -- packet := *pPacket | |
19 | -- trans := packet.TransportLayer() | |
20 | -+func packetFilter(portCache *portCache, packet gopacket.Packet, whitelistDnsServers *v2router.GeoIPMatcher) (m *dnsmessage.Message, pSAddr, pSPort, pDAddr, pDPort *gopacket.Endpoint) { | |
21 | -+ //跳过非网络层的包 | |
22 | -+ if packet.NetworkLayer() == nil { | |
23 | -+ return | |
24 | -+ } | |
25 | - //跳过非传输层的包 | |
26 | -+ trans := packet.TransportLayer() | |
27 | - if trans == nil { | |
28 | - return | |
29 | - } | |
30 | -@@ -180,7 +183,7 @@ func packetFilter(portCache *portCache, | |
31 | - } | |
32 | - | |
33 | - func (interfaceHandle *handle) handlePacket(packet gopacket.Packet, ifname string, whitelistDnsServers *v2router.GeoIPMatcher, whitelistDomains *strmatcher.MatcherGroup) { | |
34 | -- m, sAddr, sPort, dAddr, dPort := packetFilter(interfaceHandle.portCache, &packet, whitelistDnsServers) | |
35 | -+ m, sAddr, sPort, dAddr, dPort := packetFilter(interfaceHandle.portCache, packet, whitelistDnsServers) | |
36 | - if m == nil { | |
37 | - return | |
38 | - } | |
39 | ---- a/core/specialMode/infra/supervisor.go | |
40 | -+++ b/core/specialMode/infra/supervisor.go | |
41 | -@@ -9,7 +9,6 @@ import ( | |
42 | - v2router "github.com/v2rayA/v2ray-lib/router" | |
43 | - "github.com/v2rayA/v2rayA/pkg/util/log" | |
44 | - "sync" | |
45 | -- "time" | |
46 | - ) | |
47 | - | |
48 | - type DnsSupervisor struct { | |
49 | -@@ -70,7 +69,7 @@ func (d *DnsSupervisor) DeleteHandles(if | |
50 | - } | |
51 | - close(d.handles[ifname].done) | |
52 | - delete(d.handles, ifname) | |
53 | -- log.Trace("DnsSupervisor:%v closed", ifname) | |
54 | -+ log.Trace("DnsSupervisor:%v deleted", ifname) | |
55 | - return | |
56 | - } | |
57 | - | |
58 | -@@ -81,28 +80,24 @@ func (d *DnsSupervisor) Run(ifname strin | |
59 | - d.inner.Lock() | |
60 | - handle, ok := d.handles[ifname] | |
61 | - if !ok { | |
62 | -+ d.inner.Unlock() | |
63 | - return fmt.Errorf("Run: %v not exsits", ifname) | |
64 | - } | |
65 | - if handle.running { | |
66 | -+ d.inner.Unlock() | |
67 | - return fmt.Errorf("Run: %v is running", ifname) | |
68 | - } | |
69 | - handle.running = true | |
70 | - log.Trace("[DnsSupervisor] " + ifname + ": running") | |
71 | -- pkgsrc := gopacket.NewPacketSource(handle, layers.LayerTypeEthernet) | |
72 | -+ // we only decode UDP packets | |
73 | -+ pkgsrc := gopacket.NewPacketSource(handle, layers.LayerTypeDNS) | |
74 | - pkgsrc.NoCopy = true | |
75 | -+ //pkgsrc.Lazy = true | |
76 | - d.inner.Unlock() | |
77 | - packets := pkgsrc.Packets() | |
78 | - go func() { | |
79 | -- for { | |
80 | -- //心跳包,防止内存泄漏 | |
81 | -- packets <- gopacket.NewPacket(nil, layers.LinkTypeEthernet, gopacket.DecodeOptions{}) | |
82 | -- select { | |
83 | -- case <-handle.done: | |
84 | -- return | |
85 | -- default: | |
86 | -- time.Sleep(2 * time.Second) | |
87 | -- } | |
88 | -- } | |
89 | -+ <-handle.done | |
90 | -+ packets <- gopacket.NewPacket(nil, layers.LinkTypeEthernet, pkgsrc.DecodeOptions) | |
91 | - }() | |
92 | - out: | |
93 | - for packet := range packets { | |
94 | -@@ -113,5 +108,6 @@ out: | |
95 | - } | |
96 | - go handle.handlePacket(packet, ifname, whitelistDnsServers, whitelistDomains) | |
97 | - } | |
98 | -+ log.Trace("DnsSupervisor:%v closed", ifname) | |
99 | - return | |
100 | - } |
@@ -1,52 +0,0 @@ | ||
1 | -From 153b72ed623876ad73b731c2ec2344e9057d3c35 Mon Sep 17 00:00:00 2001 | |
2 | -From: mzz2017 <mzz@tuta.io> | |
3 | -Date: Wed, 21 Sep 2022 16:50:24 +0800 | |
4 | -Subject: [PATCH] fix: unexpected exit does not apply stop steps | |
5 | - | |
6 | ---- | |
7 | - service/core/v2ray/process.go | 4 ++-- | |
8 | - service/core/v2ray/processManager.go | 8 +++----- | |
9 | - 2 files changed, 5 insertions(+), 7 deletions(-) | |
10 | - | |
11 | ---- a/core/v2ray/process.go | |
12 | -+++ b/core/v2ray/process.go | |
13 | -@@ -35,7 +35,7 @@ type Process struct { | |
14 | - tag2WhichIndex map[string]int | |
15 | - } | |
16 | - | |
17 | --func NewProcess(tmpl *Template, prestart func() error, poststart func() error) (process *Process, err error) { | |
18 | -+func NewProcess(tmpl *Template, prestart func() error, poststart func() error, stopfunc func(p *Process)) (process *Process, err error) { | |
19 | - process = &Process{ | |
20 | - template: tmpl, | |
21 | - } | |
22 | -@@ -111,7 +111,7 @@ func NewProcess(tmpl *Template, prestart | |
23 | - // canceled by v2rayA | |
24 | - return | |
25 | - } | |
26 | -- defer ProcessManager.Stop(false) | |
27 | -+ defer stopfunc(process) | |
28 | - var t []string | |
29 | - if p != nil { | |
30 | - if p.Success() { | |
31 | ---- a/core/v2ray/processManager.go | |
32 | -+++ b/core/v2ray/processManager.go | |
33 | -@@ -245,16 +245,14 @@ func (m *CoreProcessManager) Start(t *Te | |
34 | - return m.beforeStart(t) | |
35 | - }, func() error { | |
36 | - return m.afterStart(t) | |
37 | -+ }, func(p *Process) { | |
38 | -+ m.p = p | |
39 | -+ ProcessManager.Stop(false) | |
40 | - }) | |
41 | - if err != nil { | |
42 | - return err | |
43 | - } | |
44 | - m.p = process | |
45 | -- defer func() { | |
46 | -- if err != nil { | |
47 | -- m.stop(true) | |
48 | -- } | |
49 | -- }() | |
50 | - | |
51 | - configure.SetRunning(true) | |
52 | - return nil |
@@ -1,336 +0,0 @@ | ||
1 | -From 00366b224b2e28861b80f677e8aa604c5d08dae3 Mon Sep 17 00:00:00 2001 | |
2 | -From: Kelo <meetkelo@outlook.com> | |
3 | -Date: Sat, 29 Oct 2022 16:27:26 +0800 | |
4 | -Subject: [PATCH] optimize: reduce disk writes | |
5 | - | |
6 | ---- | |
7 | - service/db/boltdb.go | 43 +++++++++++++++++++++++++++++++---- | |
8 | - service/db/listOp.go | 48 +++++++++++++++++++++------------------ | |
9 | - service/db/plainOp.go | 52 ++++++++++++++++++++++++------------------- | |
10 | - service/db/setOp.go | 20 +++++++++-------- | |
11 | - 4 files changed, 105 insertions(+), 58 deletions(-) | |
12 | - | |
13 | ---- a/db/boltdb.go | |
14 | -+++ b/db/boltdb.go | |
15 | -@@ -1,13 +1,14 @@ | |
16 | - package db | |
17 | - | |
18 | - import ( | |
19 | -- "go.etcd.io/bbolt" | |
20 | -- "github.com/v2rayA/v2rayA/conf" | |
21 | -- "github.com/v2rayA/v2rayA/pkg/util/copyfile" | |
22 | -- "github.com/v2rayA/v2rayA/pkg/util/log" | |
23 | - "os" | |
24 | - "path/filepath" | |
25 | - "sync" | |
26 | -+ | |
27 | -+ "github.com/v2rayA/v2rayA/conf" | |
28 | -+ "github.com/v2rayA/v2rayA/pkg/util/copyfile" | |
29 | -+ "github.com/v2rayA/v2rayA/pkg/util/log" | |
30 | -+ "go.etcd.io/bbolt" | |
31 | - ) | |
32 | - | |
33 | - var once sync.Once | |
34 | -@@ -46,3 +47,37 @@ func DB() *bbolt.DB { | |
35 | - once.Do(initDB) | |
36 | - return db | |
37 | - } | |
38 | -+ | |
39 | -+// The function should return a dirty flag. | |
40 | -+// If the dirty flag is true and there is no error then the transaction is commited. | |
41 | -+// Otherwise, the transaction is rolled back. | |
42 | -+func Transaction(db *bbolt.DB, fn func(*bbolt.Tx) (bool, error)) error { | |
43 | -+ tx, err := db.Begin(true) | |
44 | -+ if err != nil { | |
45 | -+ return err | |
46 | -+ } | |
47 | -+ defer tx.Rollback() | |
48 | -+ dirty, err := fn(tx) | |
49 | -+ if err != nil { | |
50 | -+ _ = tx.Rollback() | |
51 | -+ return err | |
52 | -+ } | |
53 | -+ if !dirty { | |
54 | -+ return nil | |
55 | -+ } | |
56 | -+ return tx.Commit() | |
57 | -+} | |
58 | -+ | |
59 | -+// If the bucket does not exist, the dirty flag is setted | |
60 | -+func CreateBucketIfNotExists(tx *bbolt.Tx, name []byte, dirty *bool) (*bbolt.Bucket, error) { | |
61 | -+ bkt := tx.Bucket(name) | |
62 | -+ if bkt != nil { | |
63 | -+ return bkt, nil | |
64 | -+ } | |
65 | -+ bkt, err := tx.CreateBucket(name) | |
66 | -+ if err != nil { | |
67 | -+ return nil, err | |
68 | -+ } | |
69 | -+ *dirty = true | |
70 | -+ return bkt, nil | |
71 | -+} | |
72 | ---- a/db/listOp.go | |
73 | -+++ b/db/listOp.go | |
74 | -@@ -2,13 +2,14 @@ package db | |
75 | - | |
76 | - import ( | |
77 | - "fmt" | |
78 | -- "go.etcd.io/bbolt" | |
79 | -- jsoniter "github.com/json-iterator/go" | |
80 | -- "github.com/tidwall/gjson" | |
81 | -- "github.com/tidwall/sjson" | |
82 | - "reflect" | |
83 | - "sort" | |
84 | - "strconv" | |
85 | -+ | |
86 | -+ jsoniter "github.com/json-iterator/go" | |
87 | -+ "github.com/tidwall/gjson" | |
88 | -+ "github.com/tidwall/sjson" | |
89 | -+ "go.etcd.io/bbolt" | |
90 | - ) | |
91 | - | |
92 | - func ListSet(bucket string, key string, index int, val interface{}) (err error) { | |
93 | -@@ -31,20 +32,21 @@ func ListSet(bucket string, key string, | |
94 | - } | |
95 | - | |
96 | - func ListGet(bucket string, key string, index int) (b []byte, err error) { | |
97 | -- err = DB().Update(func(tx *bbolt.Tx) error { | |
98 | -- if bkt, err := tx.CreateBucketIfNotExists([]byte(bucket)); err != nil { | |
99 | -- return err | |
100 | -+ err = Transaction(DB(), func(tx *bbolt.Tx) (bool, error) { | |
101 | -+ dirty := false | |
102 | -+ if bkt, err := CreateBucketIfNotExists(tx, []byte(bucket), &dirty); err != nil { | |
103 | -+ return dirty, err | |
104 | - } else { | |
105 | - v := bkt.Get([]byte(key)) | |
106 | - if v == nil { | |
107 | -- return fmt.Errorf("ListGet: can't get element from an empty list") | |
108 | -+ return dirty, fmt.Errorf("ListGet: can't get element from an empty list") | |
109 | - } | |
110 | - r := gjson.GetBytes(v, strconv.Itoa(index)) | |
111 | - if r.Exists() { | |
112 | - b = []byte(r.Raw) | |
113 | -- return nil | |
114 | -+ return dirty, nil | |
115 | - } else { | |
116 | -- return fmt.Errorf("ListGet: no such element") | |
117 | -+ return dirty, fmt.Errorf("ListGet: no such element") | |
118 | - } | |
119 | - } | |
120 | - }) | |
121 | -@@ -79,24 +81,25 @@ func ListAppend(bucket string, key strin | |
122 | - } | |
123 | - | |
124 | - func ListGetAll(bucket string, key string) (list [][]byte, err error) { | |
125 | -- err = DB().Update(func(tx *bbolt.Tx) error { | |
126 | -- if bkt, err := tx.CreateBucketIfNotExists([]byte(bucket)); err != nil { | |
127 | -- return err | |
128 | -+ err = Transaction(DB(), func(tx *bbolt.Tx) (bool, error) { | |
129 | -+ dirty := false | |
130 | -+ if bkt, err := CreateBucketIfNotExists(tx, []byte(bucket), &dirty); err != nil { | |
131 | -+ return dirty, err | |
132 | - } else { | |
133 | - b := bkt.Get([]byte(key)) | |
134 | - if b == nil { | |
135 | -- return nil | |
136 | -+ return dirty, nil | |
137 | - } | |
138 | - parsed := gjson.ParseBytes(b) | |
139 | - if !parsed.IsArray() { | |
140 | -- return fmt.Errorf("ListGetAll: is not array") | |
141 | -+ return dirty, fmt.Errorf("ListGetAll: is not array") | |
142 | - } | |
143 | - results := parsed.Array() | |
144 | - for _, r := range results { | |
145 | - list = append(list, []byte(r.Raw)) | |
146 | - } | |
147 | - } | |
148 | -- return nil | |
149 | -+ return dirty, nil | |
150 | - }) | |
151 | - return list, err | |
152 | - } | |
153 | -@@ -143,21 +146,22 @@ func ListRemove(bucket, key string, inde | |
154 | - } | |
155 | - | |
156 | - func ListLen(bucket string, key string) (length int, err error) { | |
157 | -- err = DB().Update(func(tx *bbolt.Tx) error { | |
158 | -- if bkt, err := tx.CreateBucketIfNotExists([]byte(bucket)); err != nil { | |
159 | -- return err | |
160 | -+ err = Transaction(DB(), func(tx *bbolt.Tx) (bool, error) { | |
161 | -+ dirty := false | |
162 | -+ if bkt, err := CreateBucketIfNotExists(tx, []byte(bucket), &dirty); err != nil { | |
163 | -+ return dirty, err | |
164 | - } else { | |
165 | - b := bkt.Get([]byte(key)) | |
166 | - if b == nil { | |
167 | -- return nil | |
168 | -+ return dirty, nil | |
169 | - } | |
170 | - parsed := gjson.ParseBytes(b) | |
171 | - if !parsed.IsArray() { | |
172 | -- return fmt.Errorf("ListLen: is not array") | |
173 | -+ return dirty, fmt.Errorf("ListLen: is not array") | |
174 | - } | |
175 | - length = len(parsed.Array()) | |
176 | - } | |
177 | -- return nil | |
178 | -+ return dirty, nil | |
179 | - }) | |
180 | - return length, err | |
181 | - } | |
182 | ---- a/db/plainOp.go | |
183 | -+++ b/db/plainOp.go | |
184 | -@@ -2,50 +2,54 @@ package db | |
185 | - | |
186 | - import ( | |
187 | - "fmt" | |
188 | -- "go.etcd.io/bbolt" | |
189 | -+ | |
190 | - jsoniter "github.com/json-iterator/go" | |
191 | - "github.com/v2rayA/v2rayA/common" | |
192 | - "github.com/v2rayA/v2rayA/pkg/util/log" | |
193 | -+ "go.etcd.io/bbolt" | |
194 | - ) | |
195 | - | |
196 | - func Get(bucket string, key string, val interface{}) (err error) { | |
197 | -- return DB().Update(func(tx *bbolt.Tx) error { | |
198 | -- if bkt, err := tx.CreateBucketIfNotExists([]byte(bucket)); err != nil { | |
199 | -- return err | |
200 | -+ return Transaction(DB(), func(tx *bbolt.Tx) (bool, error) { | |
201 | -+ dirty := false | |
202 | -+ if bkt, err := CreateBucketIfNotExists(tx, []byte(bucket), &dirty); err != nil { | |
203 | -+ return dirty, err | |
204 | - } else { | |
205 | - if v := bkt.Get([]byte(key)); v == nil { | |
206 | -- return fmt.Errorf("Get: key is not found") | |
207 | -+ return dirty, fmt.Errorf("Get: key is not found") | |
208 | - } else { | |
209 | -- return jsoniter.Unmarshal(v, val) | |
210 | -+ return dirty, jsoniter.Unmarshal(v, val) | |
211 | - } | |
212 | - } | |
213 | - }) | |
214 | - } | |
215 | - | |
216 | - func GetRaw(bucket string, key string) (b []byte, err error) { | |
217 | -- err = DB().Update(func(tx *bbolt.Tx) error { | |
218 | -- if bkt, err := tx.CreateBucketIfNotExists([]byte(bucket)); err != nil { | |
219 | -- return err | |
220 | -+ err = Transaction(DB(), func(tx *bbolt.Tx) (bool, error) { | |
221 | -+ dirty := false | |
222 | -+ if bkt, err := CreateBucketIfNotExists(tx, []byte(bucket), &dirty); err != nil { | |
223 | -+ return dirty, err | |
224 | - } else { | |
225 | - v := bkt.Get([]byte(key)) | |
226 | - if v == nil { | |
227 | -- return fmt.Errorf("GetRaw: key is not found") | |
228 | -+ return dirty, fmt.Errorf("GetRaw: key is not found") | |
229 | - } | |
230 | - b = common.BytesCopy(v) | |
231 | -- return nil | |
232 | -+ return dirty, nil | |
233 | - } | |
234 | - }) | |
235 | - return b, err | |
236 | - } | |
237 | - | |
238 | - func Exists(bucket string, key string) (exists bool) { | |
239 | -- if err := DB().Update(func(tx *bbolt.Tx) error { | |
240 | -- if bkt, err := tx.CreateBucketIfNotExists([]byte(bucket)); err != nil { | |
241 | -- return err | |
242 | -+ if err := Transaction(DB(), func(tx *bbolt.Tx) (bool, error) { | |
243 | -+ dirty := false | |
244 | -+ if bkt, err := CreateBucketIfNotExists(tx, []byte(bucket), &dirty); err != nil { | |
245 | -+ return dirty, err | |
246 | - } else { | |
247 | - v := bkt.Get([]byte(key)) | |
248 | - exists = v != nil | |
249 | -- return nil | |
250 | -+ return dirty, nil | |
251 | - } | |
252 | - }); err != nil { | |
253 | - log.Warn("%v", err) | |
254 | -@@ -55,23 +59,25 @@ func Exists(bucket string, key string) ( | |
255 | - } | |
256 | - | |
257 | - func GetBucketLen(bucket string) (length int, err error) { | |
258 | -- err = DB().Update(func(tx *bbolt.Tx) error { | |
259 | -- if bkt, err := tx.CreateBucketIfNotExists([]byte(bucket)); err != nil { | |
260 | -- return err | |
261 | -+ err = Transaction(DB(), func(tx *bbolt.Tx) (bool, error) { | |
262 | -+ dirty := false | |
263 | -+ if bkt, err := CreateBucketIfNotExists(tx, []byte(bucket), &dirty); err != nil { | |
264 | -+ return dirty, err | |
265 | - } else { | |
266 | - length = bkt.Stats().KeyN | |
267 | - } | |
268 | -- return nil | |
269 | -+ return dirty, nil | |
270 | - }) | |
271 | - return length, err | |
272 | - } | |
273 | - | |
274 | - func GetBucketKeys(bucket string) (keys []string, err error) { | |
275 | -- err = DB().Update(func(tx *bbolt.Tx) error { | |
276 | -- if bkt, err := tx.CreateBucketIfNotExists([]byte(bucket)); err != nil { | |
277 | -- return err | |
278 | -+ err = Transaction(DB(), func(tx *bbolt.Tx) (bool, error) { | |
279 | -+ dirty := false | |
280 | -+ if bkt, err := CreateBucketIfNotExists(tx, []byte(bucket), &dirty); err != nil { | |
281 | -+ return dirty, err | |
282 | - } else { | |
283 | -- return bkt.ForEach(func(k, v []byte) error { | |
284 | -+ return dirty, bkt.ForEach(func(k, v []byte) error { | |
285 | - keys = append(keys, string(k)) | |
286 | - return nil | |
287 | - }) | |
288 | ---- a/db/setOp.go | |
289 | -+++ b/db/setOp.go | |
290 | -@@ -4,8 +4,9 @@ import ( | |
291 | - "bytes" | |
292 | - "crypto/sha256" | |
293 | - "encoding/gob" | |
294 | -- "go.etcd.io/bbolt" | |
295 | -+ | |
296 | - "github.com/v2rayA/v2rayA/common" | |
297 | -+ "go.etcd.io/bbolt" | |
298 | - ) | |
299 | - | |
300 | - type set map[[32]byte]interface{} | |
301 | -@@ -28,26 +29,27 @@ func toSha256(val interface{}) (hash [32 | |
302 | - } | |
303 | - | |
304 | - func setOp(bucket string, key string, f func(m set) (readonly bool, err error)) (err error) { | |
305 | -- return DB().Update(func(tx *bbolt.Tx) error { | |
306 | -- if bkt, err := tx.CreateBucketIfNotExists([]byte(bucket)); err != nil { | |
307 | -- return err | |
308 | -+ return Transaction(DB(), func(tx *bbolt.Tx) (bool, error) { | |
309 | -+ dirty := false | |
310 | -+ if bkt, err := CreateBucketIfNotExists(tx, []byte(bucket), &dirty); err != nil { | |
311 | -+ return dirty, err | |
312 | - } else { | |
313 | - var m set | |
314 | - v := bkt.Get([]byte(key)) | |
315 | - if v == nil { | |
316 | - m = make(set) | |
317 | - } else if err := gob.NewDecoder(bytes.NewReader(v)).Decode(&m); err != nil { | |
318 | -- return err | |
319 | -+ return dirty, err | |
320 | - } | |
321 | - if readonly, err := f(m); err != nil { | |
322 | -- return err | |
323 | -+ return dirty, err | |
324 | - } else if readonly { | |
325 | -- return nil | |
326 | -+ return dirty, nil | |
327 | - } | |
328 | - if b, err := common.ToBytes(m); err != nil { | |
329 | -- return err | |
330 | -+ return dirty, err | |
331 | - } else { | |
332 | -- return bkt.Put([]byte(key), b) | |
333 | -+ return true, bkt.Put([]byte(key), b) | |
334 | - } | |
335 | - } | |
336 | - }) |
@@ -1,27 +0,0 @@ | ||
1 | -From 451912074ba1ba4000c66874876bc0a6b64cb5da Mon Sep 17 00:00:00 2001 | |
2 | -From: Kelo <meetkelo@outlook.com> | |
3 | -Date: Sun, 30 Oct 2022 16:49:22 +0800 | |
4 | -Subject: [PATCH] fix: do not rollback closed transaction | |
5 | - | |
6 | ---- | |
7 | - service/db/boltdb.go | 3 +-- | |
8 | - 1 file changed, 1 insertion(+), 2 deletions(-) | |
9 | - | |
10 | ---- a/db/boltdb.go | |
11 | -+++ b/db/boltdb.go | |
12 | -@@ -56,14 +56,13 @@ func Transaction(db *bbolt.DB, fn func(* | |
13 | - if err != nil { | |
14 | - return err | |
15 | - } | |
16 | -- defer tx.Rollback() | |
17 | - dirty, err := fn(tx) | |
18 | - if err != nil { | |
19 | - _ = tx.Rollback() | |
20 | - return err | |
21 | - } | |
22 | - if !dirty { | |
23 | -- return nil | |
24 | -+ return tx.Rollback() | |
25 | - } | |
26 | - return tx.Commit() | |
27 | - } |
@@ -1,88 +0,0 @@ | ||
1 | -From 58a6cf270e43ec3eaeef7d1c65de76278dd6d349 Mon Sep 17 00:00:00 2001 | |
2 | -From: mzz2017 <2017@duck.com> | |
3 | -Date: Mon, 13 Feb 2023 14:42:07 +0800 | |
4 | -Subject: [PATCH] fix: simple-obfs | |
5 | - | |
6 | ---- | |
7 | - service/pkg/plugin/simpleobfs/http.go | 8 +++++++- | |
8 | - service/pkg/plugin/simpleobfs/tls.go | 7 +++++++ | |
9 | - 2 files changed, 14 insertions(+), 1 deletion(-) | |
10 | - | |
11 | ---- a/pkg/plugin/simpleobfs/http.go | |
12 | -+++ b/pkg/plugin/simpleobfs/http.go | |
13 | -@@ -12,6 +12,7 @@ import ( | |
14 | - "net" | |
15 | - "net/http" | |
16 | - "strings" | |
17 | -+ "sync" | |
18 | - ) | |
19 | - | |
20 | - // HTTPObfs is shadowsocks http simple-obfs implementation | |
21 | -@@ -24,9 +25,13 @@ type HTTPObfs struct { | |
22 | - offset int | |
23 | - firstRequest bool | |
24 | - firstResponse bool | |
25 | -+ rMu sync.Mutex | |
26 | -+ wMu sync.Mutex | |
27 | - } | |
28 | - | |
29 | - func (ho *HTTPObfs) Read(b []byte) (int, error) { | |
30 | -+ ho.rMu.Lock() | |
31 | -+ defer ho.rMu.Unlock() | |
32 | - if ho.buf != nil { | |
33 | - n := copy(b, ho.buf[ho.offset:]) | |
34 | - ho.offset += n | |
35 | -@@ -64,6 +69,8 @@ func (ho *HTTPObfs) Read(b []byte) (int, | |
36 | - } | |
37 | - | |
38 | - func (ho *HTTPObfs) Write(b []byte) (int, error) { | |
39 | -+ ho.wMu.Lock() | |
40 | -+ defer ho.wMu.Unlock() | |
41 | - if ho.firstRequest { | |
42 | - randBytes := make([]byte, 16) | |
43 | - rand.Read(randBytes) | |
44 | -@@ -71,7 +78,6 @@ func (ho *HTTPObfs) Write(b []byte) (int | |
45 | - req.Header.Set("User-Agent", fmt.Sprintf("curl/7.%d.%d", rand.Int()%54, rand.Int()%2)) | |
46 | - req.Header.Set("Upgrade", "websocket") | |
47 | - req.Header.Set("Connection", "Upgrade") | |
48 | -- req.Host = ho.host | |
49 | - if ho.port != "80" { | |
50 | - req.Host = fmt.Sprintf("%s:%s", ho.host, ho.port) | |
51 | - } | |
52 | ---- a/pkg/plugin/simpleobfs/tls.go | |
53 | -+++ b/pkg/plugin/simpleobfs/tls.go | |
54 | -@@ -8,6 +8,7 @@ import ( | |
55 | - "io" | |
56 | - "math/rand" | |
57 | - "net" | |
58 | -+ "sync" | |
59 | - "time" | |
60 | - ) | |
61 | - | |
62 | -@@ -26,6 +27,8 @@ type TLSObfs struct { | |
63 | - remain int | |
64 | - firstRequest bool | |
65 | - firstResponse bool | |
66 | -+ rMu sync.Mutex | |
67 | -+ wMu sync.Mutex | |
68 | - } | |
69 | - | |
70 | - func (to *TLSObfs) read(b []byte, discardN int) (int, error) { | |
71 | -@@ -54,6 +57,8 @@ func (to *TLSObfs) read(b []byte, discar | |
72 | - } | |
73 | - | |
74 | - func (to *TLSObfs) Read(b []byte) (int, error) { | |
75 | -+ to.rMu.Lock() | |
76 | -+ defer to.rMu.Unlock() | |
77 | - if to.remain > 0 { | |
78 | - length := to.remain | |
79 | - if length > len(b) { | |
80 | -@@ -77,6 +82,8 @@ func (to *TLSObfs) Read(b []byte) (int, | |
81 | - return to.read(b, 3) | |
82 | - } | |
83 | - func (to *TLSObfs) Write(b []byte) (int, error) { | |
84 | -+ to.wMu.Lock() | |
85 | -+ defer to.wMu.Unlock() | |
86 | - length := len(b) | |
87 | - for i := 0; i < length; i += chunkSize { | |
88 | - end := i + chunkSize |
@@ -22,13 +22,13 @@ chore: small change in table format | ||
22 | 22 | --- a/conf/environmentConfig.go |
23 | 23 | +++ b/conf/environmentConfig.go |
24 | 24 | @@ -24,6 +24,7 @@ type Params struct { |
25 | - WebDir string `id:"webdir" desc:"v2rayA web files directory. use embedded files if not specify."` | |
26 | - VlessGrpcInboundCertKey []string `id:"vless-grpc-inbound-cert-key" desc:"Specify the certification path instead of automatically generating a self-signed certificate. Example: /etc/v2raya/grpc_certificate.crt,/etc/v2raya/grpc_private.key"` | |
27 | - IPV6Support string `id:"ipv6-support" default:"auto" desc:"Optional values: auto, on, off. Make sure your IPv6 network works fine before you turn it on."` | |
28 | -+ NFTablesSupport string `id:"nftables-support" default:"off" desc:"Optional values: auto, on, off. Experimental feature. Make sure you have installed nftables."` | |
29 | - PassCheckRoot bool `desc:"Skip privilege checking. Use it only when you cannot start v2raya but confirm you have root privilege"` | |
30 | - ResetPassword bool `id:"reset-password"` | |
31 | - LogLevel string `id:"log-level" default:"info" desc:"Optional values: trace, debug, info, warn or error"` | |
25 | + PluginManager string `id:"plugin-manager" desc:"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."` | |
26 | + WebDir string `id:"webdir" desc:"v2rayA web files directory. use embedded files if not specify."` | |
27 | + IPV6Support string `id:"ipv6-support" default:"auto" desc:"Optional values: auto, on, off. Make sure your IPv6 network works fine before you turn it on."` | |
28 | ++ NFTablesSupport string `id:"nftables-support" default:"off" desc:"Optional values: auto, on, off. Experimental feature. Make sure you have installed nftables."` | |
29 | + PassCheckRoot bool `id:"passcheckroot" desc:"Skip privilege checking. Use it only when you cannot start v2raya but confirm you have root privilege"` | |
30 | + ResetPassword bool `id:"reset-password" ignore:"1"` | |
31 | + LogLevel string `id:"log-level" default:"info" desc:"Optional values: trace, debug, info, warn or error"` | |
32 | 32 | --- a/core/iptables/dropSpoofing.go |
33 | 33 | +++ b/core/iptables/dropSpoofing.go |
34 | 34 | @@ -34,7 +34,7 @@ ip6tables -w 2 -I FORWARD -j DROP_SPOOFI |
@@ -65,17 +65,15 @@ chore: small change in table format | ||
65 | 65 | ) |
66 | 66 | |
67 | 67 | // http://briteming.hatenablog.com/entry/2019/06/18/175518 |
68 | -@@ -56,6 +57,10 @@ func (c Setter) Run(stopAtError bool) er | |
68 | +@@ -56,7 +57,7 @@ func (c Setter) Run(stopAtError bool) er | |
69 | 69 | if common.IsDocker() { |
70 | 70 | commands = strings.ReplaceAll(commands, "iptables", "iptables-legacy") |
71 | 71 | commands = strings.ReplaceAll(commands, "ip6tables", "ip6tables-legacy") |
72 | +- } else if !cmds.IsCommandValid("iptables") && | |
72 | 73 | + } else if (!cmds.IsCommandValid("iptables") || IsNFTablesSupported()) && |
73 | -+ cmds.IsCommandValid("iptables-nft") { | |
74 | -+ commands = strings.ReplaceAll(commands, "iptables", "iptables-nft") | |
75 | -+ commands = strings.ReplaceAll(commands, "ip6tables", "ip6tables-nft") | |
76 | - } | |
77 | - var errs []error | |
78 | - if c.PreFunc != nil { | |
74 | + cmds.IsCommandValid("iptables-nft") { | |
75 | + commands = strings.ReplaceAll(commands, "iptables", "iptables-nft") | |
76 | + commands = strings.ReplaceAll(commands, "ip6tables", "ip6tables-nft") | |
79 | 77 | --- a/core/iptables/redirect.go |
80 | 78 | +++ b/core/iptables/redirect.go |
81 | 79 | @@ -2,15 +2,34 @@ package iptables |
@@ -263,17 +261,24 @@ chore: small change in table format | ||
263 | 261 | } |
264 | 262 | --- a/core/iptables/tproxy.go |
265 | 263 | +++ b/core/iptables/tproxy.go |
266 | -@@ -2,18 +2,36 @@ package iptables | |
264 | +@@ -2,23 +2,42 @@ package iptables | |
267 | 265 | |
268 | 266 | import ( |
269 | 267 | "fmt" |
268 | +- "github.com/v2rayA/v2rayA/common/cmds" | |
269 | +- "github.com/v2rayA/v2rayA/db/configure" | |
270 | 270 | + "os" |
271 | -+ "strings" | |
271 | + "strconv" | |
272 | + "strings" | |
272 | 273 | + |
273 | - "github.com/v2rayA/v2rayA/common/cmds" | |
274 | ++ "github.com/v2rayA/v2rayA/common/cmds" | |
274 | 275 | + "github.com/v2rayA/v2rayA/core/v2ray/asset" |
275 | - "github.com/v2rayA/v2rayA/db/configure" | |
276 | -- "strings" | |
276 | ++ "github.com/v2rayA/v2rayA/db/configure" | |
277 | ++ | |
278 | + ) | |
279 | + | |
280 | + var ( | |
281 | + TproxyNotSkipBr string | |
277 | 282 | ) |
278 | 283 | |
279 | 284 | -type tproxy struct { |
@@ -304,7 +309,7 @@ chore: small change in table format | ||
304 | 309 | // avoid duplication |
305 | 310 | t.RemoveIPWhitelist(cidr) |
306 | 311 | pos := 7 |
307 | -@@ -30,7 +48,7 @@ func (t *tproxy) AddIPWhitelist(cidr str | |
312 | +@@ -38,7 +57,7 @@ func (t *tproxy) AddIPWhitelist(cidr str | |
308 | 313 | cmds.ExecCommands(commands, false) |
309 | 314 | } |
310 | 315 |
@@ -313,7 +318,7 @@ chore: small change in table format | ||
313 | 318 | var commands string |
314 | 319 | commands = fmt.Sprintf(`iptables -w 2 -t mangle -D TP_RULE -d %s -j RETURN`, cidr) |
315 | 320 | if !strings.Contains(cidr, ".") { |
316 | -@@ -40,7 +58,7 @@ func (t *tproxy) RemoveIPWhitelist(cidr | |
321 | +@@ -48,7 +67,7 @@ func (t *tproxy) RemoveIPWhitelist(cidr | |
317 | 322 | cmds.ExecCommands(commands, false) |
318 | 323 | } |
319 | 324 |
@@ -322,7 +327,7 @@ chore: small change in table format | ||
322 | 327 | commands := ` |
323 | 328 | ip rule add fwmark 0x40/0xc0 table 100 |
324 | 329 | ip route add local 0.0.0.0/0 dev lo table 100 |
325 | -@@ -158,7 +176,7 @@ ip6tables -w 2 -t mangle -A TP_MARK -j C | |
330 | +@@ -174,7 +193,7 @@ ip6tables -w 2 -t mangle -A TP_MARK -j C | |
326 | 331 | } |
327 | 332 | } |
328 | 333 |
@@ -331,8 +336,8 @@ chore: small change in table format | ||
331 | 336 | commands := ` |
332 | 337 | ip rule del fwmark 0x40/0xc0 table 100 |
333 | 338 | ip route del local 0.0.0.0/0 dev lo table 100 |
334 | -@@ -195,3 +213,166 @@ ip6tables -w 2 -t mangle -X TP_MARK | |
335 | - Cmds: commands, | |
339 | +@@ -211,3 +230,166 @@ ip6tables -w 2 -t mangle -X TP_MARK | |
340 | + Cmds: commands, | |
336 | 341 | } |
337 | 342 | } |
338 | 343 | + |
@@ -518,7 +523,7 @@ chore: small change in table format | ||
518 | 523 | func IPNet2CIDR(ipnet *net.IPNet) string { |
519 | 524 | @@ -44,3 +45,21 @@ func IsIPv6Supported() bool { |
520 | 525 | } |
521 | - return cmds.IsCommandValid("ip6tables") | |
526 | + return cmds.IsCommandValid("ip6tables") || cmds.IsCommandValid("ip6tables-nft") | |
522 | 527 | } |
523 | 528 | + |
524 | 529 | +func IsNFTablesSupported() bool { |
@@ -577,7 +582,7 @@ chore: small change in table format | ||
577 | 582 | ) |
578 | 583 | |
579 | 584 | func GetV2rayLocationAssetOverride() string { |
580 | -@@ -140,6 +141,10 @@ func GetV2rayConfigDirPath() (p string) | |
585 | +@@ -143,6 +144,10 @@ func GetV2rayConfigDirPath() (p string) | |
581 | 586 | return conf.GetEnvironmentConfig().V2rayConfigDirectory |
582 | 587 | } |
583 | 588 |
@@ -1,21 +0,0 @@ | ||
1 | ---- a/core/v2ray/process.go | |
2 | -+++ b/core/v2ray/process.go | |
3 | -@@ -226,6 +226,7 @@ func StartCoreProcess(ctx context.Contex | |
4 | - dir := path.Dir(v2rayBinPath) | |
5 | - var arguments = []string{ | |
6 | - v2rayBinPath, | |
7 | -+ "run", | |
8 | - "--config=" + asset.GetV2rayConfigPath(), | |
9 | - } | |
10 | - if confdir := asset.GetV2rayConfigDirPath(); confdir != "" { | |
11 | ---- a/core/v2ray/where/where.go | |
12 | -+++ b/core/v2ray/where/where.go | |
13 | -@@ -41,7 +41,7 @@ func GetV2rayServiceVersion() (variant V | |
14 | - if err != nil || len(v2rayPath) <= 0 { | |
15 | - return Unknown, "", fmt.Errorf("cannot find v2ray executable binary") | |
16 | - } | |
17 | -- out, err := exec.Command(v2rayPath, "-version").Output() | |
18 | -+ out, err := exec.Command(v2rayPath, "version").Output() | |
19 | - var fields []string | |
20 | - if fields = strings.Fields(strings.TrimSpace(string(out))); len(fields) < 2 { | |
21 | - return Unknown, "", fmt.Errorf("cannot parse version of v2ray") |