Skip to content

Commit 5a75852

Browse files
committed
WTF is this
1 parent 26922a7 commit 5a75852

40 files changed

+371
-501
lines changed

adapter/experimental.go

+5-12
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,13 @@ import (
44
"bytes"
55
"context"
66
"encoding/binary"
7-
"io"
87
"net"
98
"time"
109

1110
"github.com/sagernet/sing-box/common/urltest"
1211
"github.com/sagernet/sing-dns"
1312
N "github.com/sagernet/sing/common/network"
14-
"github.com/sagernet/sing/common/rw"
13+
"github.com/sagernet/sing/common/varbin"
1514
)
1615

1716
type ClashServer interface {
@@ -56,16 +55,15 @@ func (s *SavedRuleSet) MarshalBinary() ([]byte, error) {
5655
if err != nil {
5756
return nil, err
5857
}
59-
err = rw.WriteUVariant(&buffer, uint64(len(s.Content)))
58+
err = varbin.Write(&buffer, binary.BigEndian, s.Content)
6059
if err != nil {
6160
return nil, err
6261
}
63-
buffer.Write(s.Content)
6462
err = binary.Write(&buffer, binary.BigEndian, s.LastUpdated.Unix())
6563
if err != nil {
6664
return nil, err
6765
}
68-
err = rw.WriteVString(&buffer, s.LastEtag)
66+
err = varbin.Write(&buffer, binary.BigEndian, s.LastEtag)
6967
if err != nil {
7068
return nil, err
7169
}
@@ -79,12 +77,7 @@ func (s *SavedRuleSet) UnmarshalBinary(data []byte) error {
7977
if err != nil {
8078
return err
8179
}
82-
contentLen, err := rw.ReadUVariant(reader)
83-
if err != nil {
84-
return err
85-
}
86-
s.Content = make([]byte, contentLen)
87-
_, err = io.ReadFull(reader, s.Content)
80+
err = varbin.Read(reader, binary.BigEndian, &s.Content)
8881
if err != nil {
8982
return err
9083
}
@@ -94,7 +87,7 @@ func (s *SavedRuleSet) UnmarshalBinary(data []byte) error {
9487
return err
9588
}
9689
s.LastUpdated = time.Unix(lastUpdated, 0)
97-
s.LastEtag, err = rw.ReadVString(reader)
90+
err = varbin.Read(reader, binary.BigEndian, &s.LastEtag)
9891
if err != nil {
9992
return err
10093
}

adapter/router.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ type Router interface {
4545
DefaultInterface() string
4646
AutoDetectInterface() bool
4747
AutoDetectInterfaceFunc() control.Func
48-
DefaultMark() int
48+
DefaultMark() uint32
4949
NetworkMonitor() tun.NetworkUpdateMonitor
5050
InterfaceMonitor() tun.DefaultInterfaceMonitor
5151
PackageManager() tun.PackageManager

box_outbound.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ func (s *Box) startOutbounds() error {
4545
}
4646
started[outboundTag] = true
4747
canContinue = true
48-
if starter, isStarter := outboundToStart.(common.Starter); isStarter {
48+
if starter, isStarter := outboundToStart.(interface {
49+
Start() error
50+
}); isStarter {
4951
monitor.Start("initialize outbound/", outboundToStart.Type(), "[", outboundTag, "]")
5052
err := starter.Start()
5153
monitor.Finish()

cmd/internal/build_libbox/main.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ func buildAndroid() {
9393

9494
const name = "libbox.aar"
9595
copyPath := filepath.Join("..", "sing-box-for-android", "app", "libs")
96-
if rw.FileExists(copyPath) {
96+
if rw.IsDir(copyPath) {
9797
copyPath, _ = filepath.Abs(copyPath)
9898
err = rw.CopyFile(name, filepath.Join(copyPath, name))
9999
if err != nil {
@@ -134,7 +134,7 @@ func buildiOS() {
134134
}
135135

136136
copyPath := filepath.Join("..", "sing-box-for-apple")
137-
if rw.FileExists(copyPath) {
137+
if rw.IsDir(copyPath) {
138138
targetDir := filepath.Join(copyPath, "Libbox.xcframework")
139139
targetDir, _ = filepath.Abs(targetDir)
140140
os.RemoveAll(targetDir)

cmd/internal/build_shared/sdk.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ func FindSDK() {
3030
}
3131
for _, path := range searchPath {
3232
path = os.ExpandEnv(path)
33-
if rw.FileExists(filepath.Join(path, "licenses", "android-sdk-license")) {
33+
if rw.IsFile(filepath.Join(path, "licenses", "android-sdk-license")) {
3434
androidSDKPath = path
3535
break
3636
}
@@ -60,7 +60,7 @@ func FindSDK() {
6060
func findNDK() bool {
6161
const fixedVersion = "26.2.11394342"
6262
const versionFile = "source.properties"
63-
if fixedPath := filepath.Join(androidSDKPath, "ndk", fixedVersion); rw.FileExists(filepath.Join(fixedPath, versionFile)) {
63+
if fixedPath := filepath.Join(androidSDKPath, "ndk", fixedVersion); rw.IsFile(filepath.Join(fixedPath, versionFile)) {
6464
androidNDKPath = fixedPath
6565
return true
6666
}
@@ -86,7 +86,7 @@ func findNDK() bool {
8686
})
8787
for _, versionName := range versionNames {
8888
currentNDKPath := filepath.Join(androidSDKPath, "ndk", versionName)
89-
if rw.FileExists(filepath.Join(androidSDKPath, versionFile)) {
89+
if rw.IsFile(filepath.Join(androidSDKPath, versionFile)) {
9090
androidNDKPath = currentNDKPath
9191
log.Warn("reproducibility warning: using NDK version " + versionName + " instead of " + fixedVersion)
9292
return true
@@ -100,11 +100,11 @@ var GoBinPath string
100100
func FindMobile() {
101101
goBin := filepath.Join(build.Default.GOPATH, "bin")
102102
if runtime.GOOS == "windows" {
103-
if !rw.FileExists(filepath.Join(goBin, "gobind.exe")) {
103+
if !rw.IsFile(filepath.Join(goBin, "gobind.exe")) {
104104
log.Fatal("missing gomobile installation")
105105
}
106106
} else {
107-
if !rw.FileExists(filepath.Join(goBin, "gobind")) {
107+
if !rw.IsFile(filepath.Join(goBin, "gobind")) {
108108
log.Fatal("missing gomobile installation")
109109
}
110110
}

cmd/sing-box/cmd_merge.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,11 @@ func merge(outputPath string) error {
5454
return nil
5555
}
5656
}
57-
err = rw.WriteFile(outputPath, buffer.Bytes())
57+
err = rw.MkdirParent(outputPath)
58+
if err != nil {
59+
return err
60+
}
61+
err = os.WriteFile(outputPath, buffer.Bytes(), 0o644)
5862
if err != nil {
5963
return err
6064
}

cmd/sing-box/cmd_run.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ func readConfigAndMerge() (option.Options, error) {
109109
}
110110
var mergedMessage json.RawMessage
111111
for _, options := range optionsList {
112-
mergedMessage, err = badjson.MergeJSON(options.options.RawMessage, mergedMessage)
112+
mergedMessage, err = badjson.MergeJSON(options.options.RawMessage, mergedMessage, false)
113113
if err != nil {
114114
return option.Options{}, E.Cause(err, "merge config at ", options.path)
115115
}

common/geosite/reader.go

+46-28
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,24 @@
11
package geosite
22

33
import (
4+
"bufio"
5+
"encoding/binary"
46
"io"
57
"os"
8+
"sync"
9+
"sync/atomic"
610

711
E "github.com/sagernet/sing/common/exceptions"
8-
"github.com/sagernet/sing/common/rw"
12+
"github.com/sagernet/sing/common/varbin"
913
)
1014

1115
type Reader struct {
12-
reader io.ReadSeeker
13-
domainIndex map[string]int
14-
domainLength map[string]int
16+
access sync.Mutex
17+
reader io.ReadSeeker
18+
bufferedReader *bufio.Reader
19+
metadataIndex int64
20+
domainIndex map[string]int
21+
domainLength map[string]int
1522
}
1623

1724
func Open(path string) (*Reader, []string, error) {
@@ -34,15 +41,23 @@ func Open(path string) (*Reader, []string, error) {
3441
return reader, codes, nil
3542
}
3643

44+
type geositeMetadata struct {
45+
Code string
46+
Index uint64
47+
Length uint64
48+
}
49+
3750
func (r *Reader) readMetadata() error {
38-
version, err := rw.ReadByte(r.reader)
51+
counter := &readCounter{Reader: r.reader}
52+
reader := bufio.NewReader(counter)
53+
version, err := reader.ReadByte()
3954
if err != nil {
4055
return err
4156
}
4257
if version != 0 {
4358
return E.New("unknown version")
4459
}
45-
entryLength, err := rw.ReadUVariant(r.reader)
60+
entryLength, err := binary.ReadUvarint(reader)
4661
if err != nil {
4762
return err
4863
}
@@ -55,16 +70,16 @@ func (r *Reader) readMetadata() error {
5570
codeIndex uint64
5671
codeLength uint64
5772
)
58-
code, err = rw.ReadVString(r.reader)
73+
code, err = varbin.ReadValue[string](reader, binary.BigEndian)
5974
if err != nil {
6075
return err
6176
}
6277
keys[i] = code
63-
codeIndex, err = rw.ReadUVariant(r.reader)
78+
codeIndex, err = binary.ReadUvarint(reader)
6479
if err != nil {
6580
return err
6681
}
67-
codeLength, err = rw.ReadUVariant(r.reader)
82+
codeLength, err = binary.ReadUvarint(reader)
6883
if err != nil {
6984
return err
7085
}
@@ -73,6 +88,8 @@ func (r *Reader) readMetadata() error {
7388
}
7489
r.domainIndex = domainIndex
7590
r.domainLength = domainLength
91+
r.metadataIndex = counter.count - int64(reader.Buffered())
92+
r.bufferedReader = reader
7693
return nil
7794
}
7895

@@ -81,31 +98,32 @@ func (r *Reader) Read(code string) ([]Item, error) {
8198
if !exists {
8299
return nil, E.New("code ", code, " not exists!")
83100
}
84-
_, err := r.reader.Seek(int64(index), io.SeekCurrent)
101+
_, err := r.reader.Seek(r.metadataIndex+int64(index), io.SeekStart)
85102
if err != nil {
86103
return nil, err
87104
}
88-
counter := &rw.ReadCounter{Reader: r.reader}
89-
domain := make([]Item, r.domainLength[code])
90-
for i := range domain {
91-
var (
92-
item Item
93-
err error
94-
)
95-
item.Type, err = rw.ReadByte(counter)
96-
if err != nil {
97-
return nil, err
98-
}
99-
item.Value, err = rw.ReadVString(counter)
100-
if err != nil {
101-
return nil, err
102-
}
103-
domain[i] = item
105+
r.bufferedReader.Reset(r.reader)
106+
itemList := make([]Item, r.domainLength[code])
107+
err = varbin.Read(r.bufferedReader, binary.BigEndian, &itemList)
108+
if err != nil {
109+
return nil, err
104110
}
105-
_, err = r.reader.Seek(int64(-index)-counter.Count(), io.SeekCurrent)
106-
return domain, err
111+
return itemList, nil
107112
}
108113

109114
func (r *Reader) Upstream() any {
110115
return r.reader
111116
}
117+
118+
type readCounter struct {
119+
io.Reader
120+
count int64
121+
}
122+
123+
func (r *readCounter) Read(p []byte) (n int, err error) {
124+
n, err = r.Reader.Read(p)
125+
if n > 0 {
126+
atomic.AddInt64(&r.count, int64(n))
127+
}
128+
return
129+
}

common/geosite/writer.go

+11-14
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ package geosite
22

33
import (
44
"bytes"
5-
"io"
5+
"encoding/binary"
66
"sort"
77

8-
"github.com/sagernet/sing/common/rw"
8+
"github.com/sagernet/sing/common/varbin"
99
)
1010

11-
func Write(writer io.Writer, domains map[string][]Item) error {
11+
func Write(writer varbin.Writer, domains map[string][]Item) error {
1212
keys := make([]string, 0, len(domains))
1313
for code := range domains {
1414
keys = append(keys, code)
@@ -19,35 +19,32 @@ func Write(writer io.Writer, domains map[string][]Item) error {
1919
index := make(map[string]int)
2020
for _, code := range keys {
2121
index[code] = content.Len()
22-
for _, domain := range domains[code] {
23-
content.WriteByte(domain.Type)
24-
err := rw.WriteVString(content, domain.Value)
25-
if err != nil {
26-
return err
27-
}
22+
err := varbin.Write(content, binary.BigEndian, domains[code])
23+
if err != nil {
24+
return err
2825
}
2926
}
3027

31-
err := rw.WriteByte(writer, 0)
28+
err := writer.WriteByte(0)
3229
if err != nil {
3330
return err
3431
}
3532

36-
err = rw.WriteUVariant(writer, uint64(len(keys)))
33+
_, err = varbin.WriteUvarint(writer, uint64(len(keys)))
3734
if err != nil {
3835
return err
3936
}
4037

4138
for _, code := range keys {
42-
err = rw.WriteVString(writer, code)
39+
err = varbin.Write(writer, binary.BigEndian, code)
4340
if err != nil {
4441
return err
4542
}
46-
err = rw.WriteUVariant(writer, uint64(index[code]))
43+
_, err = varbin.WriteUvarint(writer, uint64(index[code]))
4744
if err != nil {
4845
return err
4946
}
50-
err = rw.WriteUVariant(writer, uint64(len(domains[code])))
47+
_, err = varbin.WriteUvarint(writer, uint64(len(domains[code])))
5148
if err != nil {
5249
return err
5350
}

0 commit comments

Comments
 (0)