Skip to content

Commit 507b691

Browse files
committed
chore: Improve domain matcher
1 parent bb5f3b0 commit 507b691

File tree

5 files changed

+162
-108
lines changed

5 files changed

+162
-108
lines changed

.github/workflows/build.yml

Lines changed: 108 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,120 +1,130 @@
11
name: build
22

33
on:
4-
release:
54
workflow_dispatch:
6-
5+
inputs:
6+
version:
7+
description: "Tag name of release"
8+
79
jobs:
810
build:
911
strategy:
10-
matrix:
11-
# Include amd64 on all platforms.
12-
goos: [ windows, linux, darwin ]
13-
goarch: [ amd64, 386 ]
14-
goamd64: [ v1, v3 ]
15-
exclude:
16-
# Exclude GOAMD64 v3 on i386
17-
- goarch: 386
18-
goamd64: v3
19-
# Exclude i386 on darwin and dragonfly.
20-
- goarch: 386
21-
goos: dragonfly
22-
- goarch: 386
23-
goos: darwin
24-
include:
25-
# BEGIN macOS ARM64
26-
- goos: darwin
27-
goarch: arm64
28-
# END macOS ARM64
29-
# BEGIN Linux ARM 5 6 7
30-
- goos: linux
31-
goarch: arm
32-
goarm: 7
33-
- goos: linux
34-
goarch: arm
35-
goarm: 6
36-
- goos: linux
37-
goarch: arm
38-
goarm: 5
39-
# END Linux ARM 5 6 7
40-
# BEGIN Android ARM 8
41-
- goos: android
42-
goarch: arm64
43-
# END Android ARM 8
44-
# Windows ARM
45-
- goos: windows
46-
goarch: arm64
47-
- goos: windows
48-
goarch: arm
49-
goarm: 7
50-
# BEGIN Other architectures
51-
# BEGIN riscv64 & ARM64
52-
- goos: linux
53-
goarch: arm64
54-
- goos: linux
55-
goarch: riscv64
56-
# END riscv64 & ARM64
57-
# BEGIN MIPS
58-
- goos: linux
59-
goarch: mips64
60-
- goos: linux
61-
goarch: mips64le
62-
- goos: linux
63-
goarch: mipsle
64-
- goos: linux
65-
goarch: mips
66-
# END MIPS
67-
# BEGIN LOONGARCH
68-
- goos: linux
69-
goarch: loong64
70-
# END LOONGARCH
71-
# BEGIN S390X
72-
- goos: linux
73-
goarch: s390x
74-
# END S390X
75-
# END Other architectures
76-
12+
matrix:
13+
# Include amd64 on all platforms.
14+
goos: [ windows, linux, darwin ]
15+
goarch: [ amd64, 386 ]
16+
goamd64: [ v1, v3 ]
17+
exclude:
18+
# Exclude GOAMD64 v3 on i386
19+
- goarch: 386
20+
goamd64: v3
21+
# Exclude i386 on darwin and dragonfly.
22+
- goarch: 386
23+
goos: dragonfly
24+
- goarch: 386
25+
goos: darwin
26+
include:
27+
# BEGIN macOS ARM64
28+
- goos: darwin
29+
goarch: arm64
30+
# END macOS ARM64
31+
# BEGIN Linux ARM 5 6 7
32+
- goos: linux
33+
goarch: arm
34+
goarm: 7
35+
- goos: linux
36+
goarch: arm
37+
goarm: 6
38+
- goos: linux
39+
goarch: arm
40+
goarm: 5
41+
# END Linux ARM 5 6 7
42+
# BEGIN Android ARM 8
43+
- goos: android
44+
goarch: arm64
45+
# END Android ARM 8
46+
# Windows ARM
47+
- goos: windows
48+
goarch: arm64
49+
- goos: windows
50+
goarch: arm
51+
goarm: 7
52+
# BEGIN Other architectures
53+
# BEGIN riscv64 & ARM64
54+
- goos: linux
55+
goarch: arm64
56+
- goos: linux
57+
goarch: riscv64
58+
# END riscv64 & ARM64
59+
# BEGIN MIPS
60+
- goos: linux
61+
goarch: mips64
62+
- goos: linux
63+
goarch: mips64le
64+
- goos: linux
65+
goarch: mipsle
66+
- goos: linux
67+
goarch: mips
68+
# END MIPS
69+
# BEGIN LOONGARCH
70+
- goos: linux
71+
goarch: loong64
72+
# END LOONGARCH
73+
# BEGIN S390X
74+
- goos: linux
75+
goarch: s390x
76+
# END S390X
77+
# END Other architectures
78+
7779
runs-on: ubuntu-latest
7880
env:
7981
GOOS: ${{ matrix.goos }}
8082
GOARCH: ${{ matrix.goarch }}
8183
GOARM: ${{ matrix.goarm }}
8284
GOAMD64: ${{ matrix.goamd64 }}
8385
CGO_ENABLED: 0
84-
86+
BUILD_NAME: ZBProxy-${{ matrix.goos }}-${{ matrix.goarch }}-${{ matrix.goarm }}${{ matrix.goamd64 }}${{ matrix.goos == 'windows' && '.exe' || '' }}
87+
8588
steps:
86-
- uses: actions/checkout@v4
89+
- uses: actions/checkout@v4
8790

88-
- name: Set up Go
89-
uses: actions/setup-go@v5
90-
with:
91-
go-version: ^1.20
92-
check-latest: true
91+
- name: Set up Go
92+
uses: actions/setup-go@v5
93+
with:
94+
go-version: ^1.20
95+
check-latest: true
9396

94-
- name: Tidy up Go Modules
95-
run: go mod tidy
97+
- name: Tidy up Go Modules
98+
run: go mod tidy
9699

97-
- name: Get Git Commit Hash
98-
id: hash
99-
run: echo "git_hash=$(git rev-parse --short HEAD || echo "unknown version")" >> $GITHUB_OUTPUT
100+
- name: Get Git Commit Hash
101+
id: hash
102+
run: echo "git_hash=$(git rev-parse --short HEAD || echo "unknown version")" >> $GITHUB_OUTPUT
100103

101-
- name: Build
102-
run: go build -v -trimpath -ldflags '-X "github.com/layou233/zbproxy/v3/version.CommitHash=${{ steps.hash.outputs.git_hash }}" -s -w -buildid=' -o ZBProxy-${{ matrix.goos }}-${{ matrix.goarch }}-${{ matrix.goarm }}${{ matrix.goamd64 }} ./cmd/zbproxy
104+
- name: Build
105+
run: go build -v -trimpath -ldflags '-X "github.com/layou233/zbproxy/v3/version.CommitHash=${{ steps.hash.outputs.git_hash }}" -s -w -buildid=' -o $BUILD_NAME ./cmd/zbproxy
103106

104-
- name: Handle for Windows Build
105-
if: ${{ env.GOOS == 'windows' }}
106-
run: mv ZBProxy-${{ matrix.goos }}-${{ matrix.goarch }}-${{ matrix.goarm }}${{ matrix.goamd64 }} ZBProxy-${{ matrix.goos }}-${{ matrix.goarch }}-${{ matrix.goarm }}${{ matrix.goamd64 }}.exe
107+
- name: Upload Build Artifact
108+
uses: actions/upload-artifact@v4
109+
with:
110+
name: ${{ env.BUILD_NAME }}
111+
path: ${{ env.BUILD_NAME }}
107112

108-
- name: Upload a Non-Windows Build Artifact
109-
uses: actions/upload-artifact@v4
110-
if: ${{ env.GOOS != 'windows' }}
111-
with:
112-
name: ZBProxy-${{ matrix.goos }}-${{ matrix.goarch }}-${{ matrix.goarm }}${{ matrix.goamd64 }}
113-
path: ZBProxy-${{ matrix.goos }}-${{ matrix.goarch }}-${{ matrix.goarm }}${{ matrix.goamd64 }}
113+
Publish:
114+
permissions: write-all
115+
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.version }}
116+
needs: [ build ]
117+
runs-on: ubuntu-latest
118+
steps:
119+
- uses: actions/download-artifact@v4
120+
with:
121+
path: bin/
122+
merge-multiple: true
114123

115-
- name: Upload a Windows Build Artifact
116-
uses: actions/upload-artifact@v4
117-
if: ${{ env.GOOS == 'windows' }}
118-
with:
119-
name: ZBProxy-${{ matrix.goos }}-${{ matrix.goarch }}-${{ matrix.goarm }}${{ matrix.goamd64 }}.exe
120-
path: ZBProxy-${{ matrix.goos }}-${{ matrix.goarch }}-${{ matrix.goarm }}${{ matrix.goamd64 }}.exe
124+
- name: Upload Release
125+
uses: softprops/action-gh-release@v2
126+
if: ${{ success() }}
127+
with:
128+
tag_name: ${{ github.event.inputs.version }}
129+
files: bin/*
130+
prerelease: true

common/domain/builder.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ func (b *MatcherBuilder) AddDomainSuffix(domain string) {
2222
if domain[0] == '.' {
2323
b.domainList = append(b.domainList, reverseDomainSuffix(domain))
2424
} else {
25-
b.domainList = append(b.domainList, reverseDomain(domain))
26-
b.domainList = append(b.domainList, reverseRootDomainSuffix(domain))
25+
b.domainList = append(b.domainList, reverseDomainRoot(domain))
2726
}
2827
}
2928

common/domain/matcher.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ func NewMatcher(domains []string, domainSuffix []string) *Matcher {
2020
if domain[0] == '.' {
2121
domainList = append(domainList, reverseDomainSuffix(domain))
2222
} else {
23-
domainList = append(domainList, reverseDomain(domain))
24-
domainList = append(domainList, reverseRootDomainSuffix(domain))
23+
domainList = append(domainList, reverseDomainRoot(domain))
2524
}
2625
}
2726
for _, domain := range domains {
@@ -62,15 +61,14 @@ func reverseDomainSuffix(domain string) string {
6261
return string(b)
6362
}
6463

65-
func reverseRootDomainSuffix(domain string) string {
64+
func reverseDomainRoot(domain string) string {
6665
l := len(domain)
67-
b := make([]byte, l+2)
66+
b := make([]byte, l+1)
6867
for i := 0; i < l; {
6968
r, n := utf8.DecodeRuneInString(domain[i:])
7069
i += n
7170
utf8.EncodeRune(b[l-i:], r)
7271
}
73-
b[l] = '.'
74-
b[l+1] = prefixLabel
72+
b[l] = rootLabel
7573
return string(b)
7674
}

common/domain/matcher_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package domain
2+
3+
import "testing"
4+
5+
func TestMatcher(t *testing.T) {
6+
matcher := NewMatcher(
7+
[]string{ // domain
8+
"example.com", "example.org",
9+
}, []string{ // domain suffix
10+
"example.net", ".example.invalid",
11+
})
12+
if !matcher.Match("example.com") {
13+
t.Error("example.com is not matched")
14+
}
15+
if !matcher.Match("example.org") {
16+
t.Error("example.org is not matched")
17+
}
18+
if matcher.Match("sub.example.org") {
19+
t.Error("sub.example.org is matched")
20+
}
21+
if !matcher.Match("example.net") {
22+
t.Error("example.net is not matched")
23+
}
24+
if !matcher.Match("any.example.net") {
25+
t.Error("any.example.net is not matched")
26+
}
27+
if !matcher.Match("any.one.example.net") {
28+
t.Error("any.one.one.example.net is not matched")
29+
}
30+
if matcher.Match("example.invalid") {
31+
t.Error("example.invalid is matched")
32+
}
33+
if !matcher.Match("any.example.invalid") {
34+
t.Error("any.example.invalid is not matched")
35+
}
36+
}

common/domain/set.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ package domain
22

33
import "math/bits"
44

5-
const prefixLabel = '\r'
5+
const (
6+
prefixLabel = '\r'
7+
rootLabel = '\n'
8+
)
69

710
// modified from https://github.com/openacid/succinct
811

@@ -52,6 +55,13 @@ func (ss *succinctSet) Has(key string) bool {
5255
if nextLabel == prefixLabel {
5356
return true
5457
}
58+
if nextLabel == rootLabel {
59+
nextNodeId := countZeros(ss.labelBitmap, ss.ranks, bmIdx+1)
60+
hasNext := getBit(ss.leaves, nextNodeId) != 0
61+
if currentChar == '.' && hasNext {
62+
return true
63+
}
64+
}
5565
if nextLabel == currentChar {
5666
break
5767
}
@@ -66,7 +76,8 @@ func (ss *succinctSet) Has(key string) bool {
6676
if getBit(ss.labelBitmap, bmIdx) != 0 {
6777
return false
6878
}
69-
if ss.labels[bmIdx-nodeId] == prefixLabel {
79+
nextLabel := ss.labels[bmIdx-nodeId]
80+
if nextLabel == prefixLabel || nextLabel == rootLabel {
7081
return true
7182
}
7283
}

0 commit comments

Comments
 (0)