Skip to content

Commit

Permalink
chore: Improve domain matcher
Browse files Browse the repository at this point in the history
  • Loading branch information
layou233 committed Jul 18, 2024
1 parent bb5f3b0 commit 507b691
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 108 deletions.
206 changes: 108 additions & 98 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,120 +1,130 @@
name: build

on:
release:
workflow_dispatch:

inputs:
version:
description: "Tag name of release"

jobs:
build:
strategy:
matrix:
# Include amd64 on all platforms.
goos: [ windows, linux, darwin ]
goarch: [ amd64, 386 ]
goamd64: [ v1, v3 ]
exclude:
# Exclude GOAMD64 v3 on i386
- goarch: 386
goamd64: v3
# Exclude i386 on darwin and dragonfly.
- goarch: 386
goos: dragonfly
- goarch: 386
goos: darwin
include:
# BEGIN macOS ARM64
- goos: darwin
goarch: arm64
# END macOS ARM64
# BEGIN Linux ARM 5 6 7
- goos: linux
goarch: arm
goarm: 7
- goos: linux
goarch: arm
goarm: 6
- goos: linux
goarch: arm
goarm: 5
# END Linux ARM 5 6 7
# BEGIN Android ARM 8
- goos: android
goarch: arm64
# END Android ARM 8
# Windows ARM
- goos: windows
goarch: arm64
- goos: windows
goarch: arm
goarm: 7
# BEGIN Other architectures
# BEGIN riscv64 & ARM64
- goos: linux
goarch: arm64
- goos: linux
goarch: riscv64
# END riscv64 & ARM64
# BEGIN MIPS
- goos: linux
goarch: mips64
- goos: linux
goarch: mips64le
- goos: linux
goarch: mipsle
- goos: linux
goarch: mips
# END MIPS
# BEGIN LOONGARCH
- goos: linux
goarch: loong64
# END LOONGARCH
# BEGIN S390X
- goos: linux
goarch: s390x
# END S390X
# END Other architectures
matrix:
# Include amd64 on all platforms.
goos: [ windows, linux, darwin ]
goarch: [ amd64, 386 ]
goamd64: [ v1, v3 ]
exclude:
# Exclude GOAMD64 v3 on i386
- goarch: 386
goamd64: v3
# Exclude i386 on darwin and dragonfly.
- goarch: 386
goos: dragonfly
- goarch: 386
goos: darwin
include:
# BEGIN macOS ARM64
- goos: darwin
goarch: arm64
# END macOS ARM64
# BEGIN Linux ARM 5 6 7
- goos: linux
goarch: arm
goarm: 7
- goos: linux
goarch: arm
goarm: 6
- goos: linux
goarch: arm
goarm: 5
# END Linux ARM 5 6 7
# BEGIN Android ARM 8
- goos: android
goarch: arm64
# END Android ARM 8
# Windows ARM
- goos: windows
goarch: arm64
- goos: windows
goarch: arm
goarm: 7
# BEGIN Other architectures
# BEGIN riscv64 & ARM64
- goos: linux
goarch: arm64
- goos: linux
goarch: riscv64
# END riscv64 & ARM64
# BEGIN MIPS
- goos: linux
goarch: mips64
- goos: linux
goarch: mips64le
- goos: linux
goarch: mipsle
- goos: linux
goarch: mips
# END MIPS
# BEGIN LOONGARCH
- goos: linux
goarch: loong64
# END LOONGARCH
# BEGIN S390X
- goos: linux
goarch: s390x
# END S390X
# END Other architectures

runs-on: ubuntu-latest
env:
GOOS: ${{ matrix.goos }}
GOARCH: ${{ matrix.goarch }}
GOARM: ${{ matrix.goarm }}
GOAMD64: ${{ matrix.goamd64 }}
CGO_ENABLED: 0

BUILD_NAME: ZBProxy-${{ matrix.goos }}-${{ matrix.goarch }}-${{ matrix.goarm }}${{ matrix.goamd64 }}${{ matrix.goos == 'windows' && '.exe' || '' }}

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: ^1.20
check-latest: true
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: ^1.20
check-latest: true

- name: Tidy up Go Modules
run: go mod tidy
- name: Tidy up Go Modules
run: go mod tidy

- name: Get Git Commit Hash
id: hash
run: echo "git_hash=$(git rev-parse --short HEAD || echo "unknown version")" >> $GITHUB_OUTPUT
- name: Get Git Commit Hash
id: hash
run: echo "git_hash=$(git rev-parse --short HEAD || echo "unknown version")" >> $GITHUB_OUTPUT

- name: Build
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
- name: Build
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

- name: Handle for Windows Build
if: ${{ env.GOOS == 'windows' }}
run: mv ZBProxy-${{ matrix.goos }}-${{ matrix.goarch }}-${{ matrix.goarm }}${{ matrix.goamd64 }} ZBProxy-${{ matrix.goos }}-${{ matrix.goarch }}-${{ matrix.goarm }}${{ matrix.goamd64 }}.exe
- name: Upload Build Artifact
uses: actions/upload-artifact@v4
with:
name: ${{ env.BUILD_NAME }}
path: ${{ env.BUILD_NAME }}

- name: Upload a Non-Windows Build Artifact
uses: actions/upload-artifact@v4
if: ${{ env.GOOS != 'windows' }}
with:
name: ZBProxy-${{ matrix.goos }}-${{ matrix.goarch }}-${{ matrix.goarm }}${{ matrix.goamd64 }}
path: ZBProxy-${{ matrix.goos }}-${{ matrix.goarch }}-${{ matrix.goarm }}${{ matrix.goamd64 }}
Publish:
permissions: write-all
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.version }}
needs: [ build ]
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
with:
path: bin/
merge-multiple: true

- name: Upload a Windows Build Artifact
uses: actions/upload-artifact@v4
if: ${{ env.GOOS == 'windows' }}
with:
name: ZBProxy-${{ matrix.goos }}-${{ matrix.goarch }}-${{ matrix.goarm }}${{ matrix.goamd64 }}.exe
path: ZBProxy-${{ matrix.goos }}-${{ matrix.goarch }}-${{ matrix.goarm }}${{ matrix.goamd64 }}.exe
- name: Upload Release
uses: softprops/action-gh-release@v2
if: ${{ success() }}
with:
tag_name: ${{ github.event.inputs.version }}
files: bin/*
prerelease: true
3 changes: 1 addition & 2 deletions common/domain/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ func (b *MatcherBuilder) AddDomainSuffix(domain string) {
if domain[0] == '.' {
b.domainList = append(b.domainList, reverseDomainSuffix(domain))
} else {
b.domainList = append(b.domainList, reverseDomain(domain))
b.domainList = append(b.domainList, reverseRootDomainSuffix(domain))
b.domainList = append(b.domainList, reverseDomainRoot(domain))
}
}

Expand Down
10 changes: 4 additions & 6 deletions common/domain/matcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ func NewMatcher(domains []string, domainSuffix []string) *Matcher {
if domain[0] == '.' {
domainList = append(domainList, reverseDomainSuffix(domain))
} else {
domainList = append(domainList, reverseDomain(domain))
domainList = append(domainList, reverseRootDomainSuffix(domain))
domainList = append(domainList, reverseDomainRoot(domain))
}
}
for _, domain := range domains {
Expand Down Expand Up @@ -62,15 +61,14 @@ func reverseDomainSuffix(domain string) string {
return string(b)
}

func reverseRootDomainSuffix(domain string) string {
func reverseDomainRoot(domain string) string {
l := len(domain)
b := make([]byte, l+2)
b := make([]byte, l+1)
for i := 0; i < l; {
r, n := utf8.DecodeRuneInString(domain[i:])
i += n
utf8.EncodeRune(b[l-i:], r)
}
b[l] = '.'
b[l+1] = prefixLabel
b[l] = rootLabel
return string(b)
}
36 changes: 36 additions & 0 deletions common/domain/matcher_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package domain

import "testing"

func TestMatcher(t *testing.T) {
matcher := NewMatcher(
[]string{ // domain
"example.com", "example.org",
}, []string{ // domain suffix
"example.net", ".example.invalid",
})
if !matcher.Match("example.com") {
t.Error("example.com is not matched")
}
if !matcher.Match("example.org") {
t.Error("example.org is not matched")
}
if matcher.Match("sub.example.org") {
t.Error("sub.example.org is matched")
}
if !matcher.Match("example.net") {
t.Error("example.net is not matched")
}
if !matcher.Match("any.example.net") {
t.Error("any.example.net is not matched")
}
if !matcher.Match("any.one.example.net") {
t.Error("any.one.one.example.net is not matched")
}
if matcher.Match("example.invalid") {
t.Error("example.invalid is matched")
}
if !matcher.Match("any.example.invalid") {
t.Error("any.example.invalid is not matched")
}
}
15 changes: 13 additions & 2 deletions common/domain/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ package domain

import "math/bits"

const prefixLabel = '\r'
const (
prefixLabel = '\r'
rootLabel = '\n'
)

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

Expand Down Expand Up @@ -52,6 +55,13 @@ func (ss *succinctSet) Has(key string) bool {
if nextLabel == prefixLabel {
return true
}
if nextLabel == rootLabel {
nextNodeId := countZeros(ss.labelBitmap, ss.ranks, bmIdx+1)
hasNext := getBit(ss.leaves, nextNodeId) != 0
if currentChar == '.' && hasNext {
return true
}
}
if nextLabel == currentChar {
break
}
Expand All @@ -66,7 +76,8 @@ func (ss *succinctSet) Has(key string) bool {
if getBit(ss.labelBitmap, bmIdx) != 0 {
return false
}
if ss.labels[bmIdx-nodeId] == prefixLabel {
nextLabel := ss.labels[bmIdx-nodeId]
if nextLabel == prefixLabel || nextLabel == rootLabel {
return true
}
}
Expand Down

0 comments on commit 507b691

Please sign in to comment.