Chore: script built

This commit is contained in:
gVisor bot 2021-10-21 20:22:23 +08:00
parent 88be61aa1f
commit ef87959c2f
17 changed files with 139 additions and 249 deletions

View file

@ -29,6 +29,26 @@ jobs:
- name: Get dependencies, run test and static check - name: Get dependencies, run test and static check
run: | run: |
# fetch python cross compile source files
mkdir -p bin/python/
cd bin/python/
curl -LO https://raw.githubusercontent.com/yaling888/snack/main/python-3.9.7-darwin-amd64.tar.xz
curl -LO https://raw.githubusercontent.com/yaling888/snack/main/python-3.9.7-darwin-arm64.tar.xz
curl -LO https://raw.githubusercontent.com/yaling888/snack/main/python-3.9.7-windows-amd64.tar.xz
curl -LO https://raw.githubusercontent.com/yaling888/snack/main/python-3.9.7-windows-386.tar.xz
curl -LO https://raw.githubusercontent.com/yaling888/snack/main/python-3.9.7-linux-amd64.tar.xz
curl -LO https://raw.githubusercontent.com/yaling888/snack/main/python-3.9.7-linux-arm64.tar.xz
#curl -LO https://raw.githubusercontent.com/yaling888/snack/main/python-3.9.7-linux-386.tar.xz
tar -Jxf python-3.9.7-darwin-amd64.tar.xz
tar -Jxf python-3.9.7-darwin-arm64.tar.xz
tar -Jxf python-3.9.7-windows-amd64.tar.xz
tar -Jxf python-3.9.7-windows-386.tar.xz
tar -Jxf python-3.9.7-linux-amd64.tar.xz
tar -Jxf python-3.9.7-linux-arm64.tar.xz
#tar -Jxf python-3.9.7-linux-386.tar.xz
rm python-3.9.7-*.tar.xz
cd ../../
go test ./... go test ./...
go vet ./... go vet ./...
go install honnef.co/go/tools/cmd/staticcheck@latest go install honnef.co/go/tools/cmd/staticcheck@latest
@ -41,6 +61,8 @@ jobs:
- name: SSH connection to Actions - name: SSH connection to Actions
uses: P3TERX/ssh2actions@v1.0.0 uses: P3TERX/ssh2actions@v1.0.0
if: github.actor == github.repository_owner && contains(github.event.head_commit.message, '[ssh]') if: github.actor == github.repository_owner && contains(github.event.head_commit.message, '[ssh]')
env:
SSH_PASSWORD: ${{ secrets.ADAWADLHIOH }}
- name: Build - name: Build
#if: startsWith(github.ref, 'refs/tags/') #if: startsWith(github.ref, 'refs/tags/')
@ -48,11 +70,12 @@ jobs:
NAME: clash NAME: clash
BINDIR: bin BINDIR: bin
run: | run: |
make cleancache && make -j releases make -j releases
- name: Prepare upload - name: Prepare upload
if: startsWith(github.ref, 'refs/tags/') == false if: startsWith(github.ref, 'refs/tags/') == false
run: | run: |
rm -rf bin/python/
echo "FILE_DATE=_$(date +"%Y%m%d%H%M")" >> $GITHUB_ENV echo "FILE_DATE=_$(date +"%Y%m%d%H%M")" >> $GITHUB_ENV
echo "FILE_SHA=$(git describe --tags --always 2>/dev/null)" >> $GITHUB_ENV echo "FILE_SHA=$(git describe --tags --always 2>/dev/null)" >> $GITHUB_ENV
@ -83,6 +106,6 @@ jobs:
with: with:
keep_latest: 1 keep_latest: 1
delete_tags: true delete_tags: true
delete_tag_pattern: premium delete_tag_pattern: plus-pro
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View file

@ -16,27 +16,29 @@ STATIC_LDFLAGS='-X "github.com/Dreamacro/clash/constant.Version=$(VERSION)" \
-w -s -buildid=' -w -s -buildid='
PLATFORM_LIST = \ PLATFORM_LIST = \
darwin-10.12-amd64 \ darwin-amd64 \
darwin-10.15-arm64 \ darwin-arm64 \
linux-386 \
linux-amd64 \ linux-amd64 \
linux-arm64 linux-arm64
# linux-386
WINDOWS_ARCH_LIST = \ WINDOWS_ARCH_LIST = \
windows-4.0-amd64 \ windows-amd64 \
windows-4.0-386 windows-386
# windows-arm64 # windows-arm64
all: linux-amd64 darwin-10.12-amd64 windows-4.0-amd64 # Most used all: linux-amd64 darwin-amd64 windows-amd64 # Most used
build: build:
$(GOBUILD) -ldflags $(RELEASE_LDFLAGS) -o $(BINDIR)/$(NAME)-$@ $(GOBUILD) -ldflags $(RELEASE_LDFLAGS) -tags build_local -o $(BINDIR)/$(NAME)-$@
darwin-10.12-amd64: darwin-amd64:
$(XGOCMD) -dest=$(BINDIR) -out=$(NAME) -trimpath=true -ldflags=$(RELEASE_LDFLAGS) -targets=darwin-10.12/amd64 $(BUILD_PACKAGE) $(XGOCMD) -dest=$(BINDIR) -out=$(NAME) -trimpath=true -ldflags=$(RELEASE_LDFLAGS) -targets=darwin-10.12/amd64 $(BUILD_PACKAGE) && \
mv $(BINDIR)/$(NAME)-darwin-10.12-amd64 $(BINDIR)/$(NAME)-darwin-amd64
darwin-10.15-arm64: darwin-arm64:
$(XGOCMD) -dest=$(BINDIR) -out=$(NAME) -trimpath=true -ldflags=$(RELEASE_LDFLAGS) -targets=darwin-10.15/arm64 $(BUILD_PACKAGE) $(XGOCMD) -dest=$(BINDIR) -out=$(NAME) -trimpath=true -ldflags=$(RELEASE_LDFLAGS) -targets=darwin-11.1/arm64 $(BUILD_PACKAGE) && \
mv $(BINDIR)/$(NAME)-darwin-11.1-arm64 $(BINDIR)/$(NAME)-darwin-arm64
linux-386: linux-386:
$(XGOCMD) -dest=$(BINDIR) -out=$(NAME) -trimpath=true -ldflags=$(STATIC_LDFLAGS) -targets=linux/386 $(BUILD_PACKAGE) $(XGOCMD) -dest=$(BINDIR) -out=$(NAME) -trimpath=true -ldflags=$(STATIC_LDFLAGS) -targets=linux/386 $(BUILD_PACKAGE)
@ -48,14 +50,17 @@ linux-amd64:
linux-arm64: linux-arm64:
$(XGOCMD) -dest=$(BINDIR) -out=$(NAME) -trimpath=true -ldflags=$(STATIC_LDFLAGS) -targets=linux/arm64 $(BUILD_PACKAGE) $(XGOCMD) -dest=$(BINDIR) -out=$(NAME) -trimpath=true -ldflags=$(STATIC_LDFLAGS) -targets=linux/arm64 $(BUILD_PACKAGE)
windows-4.0-386: windows-386:
$(XGOCMD) -dest=$(BINDIR) -out=$(NAME) -trimpath=true -ldflags=$(RELEASE_LDFLAGS) -targets=windows-4.0/386 $(BUILD_PACKAGE) $(XGOCMD) -dest=$(BINDIR) -out=$(NAME) -trimpath=true -ldflags=$(RELEASE_LDFLAGS) -targets=windows-4.0/386 $(BUILD_PACKAGE) && \
mv $(BINDIR)/$(NAME)-windows-4.0-386.exe $(BINDIR)/$(NAME)-windows-386.exe
windows-4.0-amd64: windows-amd64:
$(XGOCMD) -dest=$(BINDIR) -out=$(NAME) -trimpath=true -ldflags=$(RELEASE_LDFLAGS) -targets=windows-4.0/amd64 $(BUILD_PACKAGE) $(XGOCMD) -dest=$(BINDIR) -out=$(NAME) -trimpath=true -ldflags=$(RELEASE_LDFLAGS) -targets=windows-4.0/amd64 $(BUILD_PACKAGE) && \
mv $(BINDIR)/$(NAME)-windows-4.0-amd64.exe $(BINDIR)/$(NAME)-windows-amd64.exe
#windows-arm64: #windows-arm64:
# $(XGOCMD) -dest=$(BINDIR) -out=$(NAME) -trimpath=true -ldflags=$(RELEASE_LDFLAGS) -targets=windows/arm64 $(BUILD_PACKAGE) # $(XGOCMD) -dest=$(BINDIR) -out=$(NAME) -trimpath=true -ldflags=$(RELEASE_LDFLAGS) -targets=windows/arm64 $(BUILD_PACKAGE)
# mv $(NAME)-windows-4.0-arm64.exe $(NAME)-windows-arm64.exe
gz_releases=$(addsuffix .gz, $(PLATFORM_LIST)) gz_releases=$(addsuffix .gz, $(PLATFORM_LIST))
zip_releases=$(addsuffix .zip, $(WINDOWS_ARCH_LIST)) zip_releases=$(addsuffix .zip, $(WINDOWS_ARCH_LIST))

View file

@ -67,17 +67,17 @@ script:
privacy: '"analytics" in host or "adservice" in host or "firebase" in host or "safebrowsing" in host or "doubleclick" in host' privacy: '"analytics" in host or "adservice" in host or "firebase" in host or "safebrowsing" in host or "doubleclick" in host'
rules: rules:
# network condition for all rules # rule SCRIPT
- SCRIPT,quic,REJECT # Disable QUIC, same as rule "DST-PORT,443,REJECT,udp"
- SCRIPT,privacy,REJECT
# network(tcp/udp) condition for all rules
- DOMAIN-SUFFIX,bilibili.com,DIRECT,tcp - DOMAIN-SUFFIX,bilibili.com,DIRECT,tcp
- DOMAIN-SUFFIX,bilibili.com,REJECT,udp - DOMAIN-SUFFIX,bilibili.com,REJECT,udp
# multiport condition for rules SRC-PORT and DST-PORT # multiport condition for rules SRC-PORT and DST-PORT
- DST-PORT,123/136/137-139,DIRECT,udp - DST-PORT,123/136/137-139,DIRECT,udp
# rule SCRIPT
- SCRIPT,quic,REJECT # Disable QUIC, same as rule "- DST-PORT,443,REJECT,udp"
- SCRIPT,privacy,REJECT
# rule GEOSITE # rule GEOSITE
- GEOSITE,category-ads-all,REJECT - GEOSITE,category-ads-all,REJECT
- GEOSITE,icloud@cn,DIRECT - GEOSITE,icloud@cn,DIRECT
@ -106,7 +106,7 @@ Script enables users to programmatically select a policy for the packets with mo
mode: script mode: script
rules: rules:
# the rule GEOSITE just as a rule provider in script mode # the rule GEOSITE just as a rule provider in mode script
- GEOSITE,category-ads-all,Whatever - GEOSITE,category-ads-all,Whatever
- GEOSITE,youtube,Whatever - GEOSITE,youtube,Whatever
- GEOSITE,geolocation-cn,Whatever - GEOSITE,geolocation-cn,Whatever
@ -138,7 +138,7 @@ script:
if ctx.rule_providers["geosite:geolocation-cn"].match(metadata): if ctx.rule_providers["geosite:geolocation-cn"].match(metadata):
ctx.log('[Script] domain %s matched geolocation-cn' % host) ctx.log('[Script] domain %s matched geolocation-cn' % host)
return "CN" return "DIRECT"
ip = metadata["dst_ip"] ip = metadata["dst_ip"]
if host != "": if host != "":
@ -153,23 +153,23 @@ script:
return "Proxy" # default policy for requests which are not matched by any other script return "Proxy" # default policy for requests which are not matched by any other script
``` ```
the context and metadata the context and metadata
```python ```ts
interface Metadata { interface Metadata {
type: string // socks5、http type: string // socks5、http
network: string // tcp network: string // tcp
host: string host: string
process_name: string process_name: string
src_ip: string src_ip: string
src_port: int src_port: int
dst_ip: string dst_ip: string
dst_port: int dst_port: int
} }
interface Context { interface Context {
resolve_ip: (host: string) => string // ip string resolve_ip: (host: string) => string // ip string
geoip: (ip: string) => string // country code geoip: (ip: string) => string // country code
log: (log: string) => void log: (log: string) => void
rule_providers: Record<string, { match: (metadata: Metadata) => boolean }> rule_providers: Record<string, { match: (metadata: Metadata) => boolean }>
} }
``` ```
@ -219,7 +219,7 @@ Create user given name `clash`.
Run Clash by user `clash` as a daemon. Run Clash by user `clash` as a daemon.
Create the systemd configuration file at /etc/systemd/system/clash.service: Create the systemd configuration file at /etc/systemd/system/clash.service:
```shell ```
[Unit] [Unit]
Description=Clash daemon, A rule-based proxy in Go. Description=Clash daemon, A rule-based proxy in Go.
After=network.target After=network.target
@ -246,7 +246,7 @@ $ systemctl start clash
``` ```
### Display Process name ### Display Process name
Add field `Process` to `Metadata` and prepare to get process name for Restful API `GET /connections`. Clash add field `Process` to `Metadata` and prepare to get process name for Restful API `GET /connections`.
To display process name in GUI please use https://yaling888.github.io/yacd/. To display process name in GUI please use https://yaling888.github.io/yacd/.

View file

@ -0,0 +1,9 @@
//go:build build_local
// +build build_local
package script
/*
#cgo pkg-config: python3-embed
*/
import "C"

View file

@ -0,0 +1,25 @@
//go:build !build_local
// +build !build_local
package script
/*
//#cgo linux,amd64 pkg-config: python-3.9-embed
#cgo darwin,amd64 CFLAGS: -I/build/python/python-3.9.7-darwin-amd64/include/python3.9
#cgo darwin,arm64 CFLAGS: -I/build/python/python-3.9.7-darwin-arm64/include/python3.9
#cgo windows,amd64 CFLAGS: -I/build/python/python-3.9.7-windows-amd64/include -DMS_WIN64
#cgo windows,386 CFLAGS: -I/build/python/python-3.9.7-windows-386/include
#cgo linux,amd64 CFLAGS: -I/home/runner/work/clash/clash/bin/python/python-3.9.7-linux-amd64/include/python3.9
#cgo linux,arm64 CFLAGS: -I/build/python/python-3.9.7-linux-arm64/include/python3.9
#cgo linux,386 CFLAGS: -I/build/python/python-3.9.7-linux-386/include/python3.9
#cgo darwin,amd64 LDFLAGS: -L/build/python/python-3.9.7-darwin-amd64/lib -lpython3.9 -ldl -framework CoreFoundation
#cgo darwin,arm64 LDFLAGS: -L/build/python/python-3.9.7-darwin-arm64/lib -lpython3.9 -ldl -framework CoreFoundation
#cgo windows,amd64 LDFLAGS: -L/build/python/python-3.9.7-windows-amd64/lib -lpython39 -lpthread -lm
#cgo windows,386 LDFLAGS: -L/build/python/python-3.9.7-windows-386/lib -lpython39 -lpthread -lm
#cgo linux,amd64 LDFLAGS: -L/home/runner/work/clash/clash/bin/python/python-3.9.7-linux-amd64/lib -lpython3.9 -lpthread -ldl -lutil -lm
#cgo linux,arm64 LDFLAGS: -L/build/python/python-3.9.7-linux-arm64/lib -lpython3.9 -lpthread -ldl -lutil -lm
#cgo linux,386 LDFLAGS: -L/build/python/python-3.9.7-linux-386/lib -lpython3.9 -lcrypt -lpthread -ldl -lutil -lm
*/
import "C"

View file

@ -37,8 +37,6 @@ void init_python(const char *path) {
import can be deferred until the embedded script import can be deferred until the embedded script
imports it. */ imports it. */
clash_module = PyImport_ImportModule("clash"); clash_module = PyImport_ImportModule("clash");
main_fn = load_func(CLASH_SCRIPT_MODULE_NAME, "main");
} }
// Load function, same as "import module_name.func_name as obj" in Python // Load function, same as "import module_name.func_name as obj" in Python
@ -87,6 +85,10 @@ void py_clear(PyObject *obj) {
Py_CLEAR(obj); Py_CLEAR(obj);
} }
void load_main_func() {
main_fn = load_func(CLASH_SCRIPT_MODULE_NAME, "main");
}
/** callback function, that call go function by python3 script. **/ /** callback function, that call go function by python3 script. **/
resolve_ip_callback resolve_ip_callback_fn; resolve_ip_callback resolve_ip_callback_fn;

View file

@ -1,10 +1,6 @@
package script package script
/* /*
#cgo pkg-config: python3-embed
//#cgo pkg-config: python3
//#cgo LDFLAGS: -lpython3
#include "clash_module.h" #include "clash_module.h"
extern const char *resolveIPCallbackFn(const char *host); extern const char *resolveIPCallbackFn(const char *host);
@ -42,6 +38,7 @@ import (
"os" "os"
"runtime" "runtime"
"strconv" "strconv"
"strings"
"sync" "sync"
"syscall" "syscall"
"unsafe" "unsafe"
@ -88,6 +85,7 @@ func Py_Initialize(path string) error {
C.finalize_Python() C.finalize_Python()
} }
path = strings.ReplaceAll(path, "\\", "/")
cPath := C.CString(path) cPath := C.CString(path)
//defer C.free(unsafe.Pointer(cPath)) //defer C.free(unsafe.Pointer(cPath))
@ -182,6 +180,15 @@ func LoadShortcutFunction(shortcut string) (*PyObject, error) {
return togo(fnc), nil return togo(fnc), nil
} }
func LoadMainFunction() error {
C.load_main_func()
err := PyLastError()
if err != nil {
return err
}
return nil
}
//CallPyMainFunction call python script main function //CallPyMainFunction call python script main function
//return the proxy adapter name. //return the proxy adapter name.
func CallPyMainFunction(mtd *constant.Metadata) (string, error) { func CallPyMainFunction(mtd *constant.Metadata) (string, error) {
@ -226,7 +233,7 @@ func CallPyMainFunction(mtd *constant.Metadata) (string, error) {
err := PyLastError() err := PyLastError()
if err != nil { if err != nil {
log.Errorln("[Script] script code error: %s", err.Error()) log.Errorln("[Script] script code error: %s", err.Error())
syscall.Kill(syscall.Getpid(), syscall.SIGINT) killSelf()
return "", fmt.Errorf("script code error: %w", err) return "", fmt.Errorf("script code error: %w", err)
} else { } else {
return "", fmt.Errorf("script code error, result: %v", rs) return "", fmt.Errorf("script code error, result: %v", rs)
@ -281,7 +288,7 @@ func CallPyShortcut(fn *PyObject, mtd *constant.Metadata) (bool, error) {
err := PyLastError() err := PyLastError()
if err != nil { if err != nil {
log.Errorln("[Script] script shortcut code error: %s", err.Error()) log.Errorln("[Script] script shortcut code error: %s", err.Error())
syscall.Kill(syscall.Getpid(), syscall.SIGINT) killSelf()
return false, fmt.Errorf("script shortcut code error: %w", err) return false, fmt.Errorf("script shortcut code error: %w", err)
} else { } else {
return false, fmt.Errorf("script shortcut code error: result: %d", rs) return false, fmt.Errorf("script shortcut code error: result: %d", rs)
@ -319,3 +326,14 @@ func NewClashPyContext(ruleProvidersName []string) error {
return nil return nil
} }
func killSelf() {
p, err := os.FindProcess(os.Getpid())
if err != nil {
os.Exit(int(syscall.SIGINT))
return
}
p.Signal(syscall.SIGINT)
}

View file

@ -30,6 +30,7 @@ void set_log_callback(log_callback cb);
void append_inittab(); void append_inittab();
void init_python(const char *path); void init_python(const char *path);
void load_main_func();
void finalize_Python(); void finalize_Python();
void py_clear(PyObject *obj); void py_clear(PyObject *obj);
const char *py_last_error(); const char *py_last_error();

View file

@ -98,7 +98,7 @@ func ruleProviderCallbackFn(cProviderName *C.char, cMetadata *C.struct_Metadata)
rule, ok := ruleProviders[providerName] rule, ok := ruleProviders[providerName]
if !ok { if !ok {
log.Warnln("rule provider [%s] not found", providerName) log.Warnln("[Script] rule provider [%s] not found", providerName)
return C.int(0) return C.int(0)
} }

View file

@ -475,10 +475,14 @@ time = ClashTime()
if err = S.Py_Initialize(C.Path.ScriptDir()); err != nil { if err = S.Py_Initialize(C.Path.ScriptDir()); err != nil {
return fmt.Errorf("initialized script module failure, %s", err.Error()) return fmt.Errorf("initialized script module failure, %s", err.Error())
} else { } else if mode == T.Script {
log.Infoln("Start initial script module successful") if err = S.LoadMainFunction(); err != nil {
return fmt.Errorf("initialized script module failure, %s", err.Error())
}
} }
log.Infoln("Start initial script module successful")
return nil return nil
} }

View file

@ -6,7 +6,7 @@ import (
"github.com/Dreamacro/clash/component/mmdb" "github.com/Dreamacro/clash/component/mmdb"
"github.com/Dreamacro/clash/component/trie" "github.com/Dreamacro/clash/component/trie"
//_ "github.com/Dreamacro/clash/rule/geodata/standard" C "github.com/Dreamacro/clash/constant"
) )
type fallbackIPFilter interface { type fallbackIPFilter interface {
@ -19,7 +19,7 @@ type geoipFilter struct {
func (gf *geoipFilter) Match(ip net.IP) bool { func (gf *geoipFilter) Match(ip net.IP) bool {
record, _ := mmdb.Instance().Country(ip) record, _ := mmdb.Instance().Country(ip)
return !strings.EqualFold(record.Country.IsoCode, gf.code) && !ip.IsPrivate() return !strings.EqualFold(record.Country.IsoCode, gf.code) && !ip.IsPrivate() && !ip.Equal(C.TunBroadcastAddr)
} }
type ipnetFilter struct { type ipnetFilter struct {

3
go.mod
View file

@ -25,7 +25,6 @@ require (
google.golang.org/protobuf v1.27.1 google.golang.org/protobuf v1.27.1
gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v2 v2.4.0
gvisor.dev/gvisor v0.0.0-20210922003438-b39716d116fd gvisor.dev/gvisor v0.0.0-20210922003438-b39716d116fd
inet.af/netaddr v0.0.0-20210903134321-85fa6c94624e
) )
require ( require (
@ -34,8 +33,6 @@ require (
github.com/oschwald/maxminddb-golang v1.8.0 // indirect github.com/oschwald/maxminddb-golang v1.8.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/u-root/uio v0.0.0-20210528114334-82958018845c // indirect github.com/u-root/uio v0.0.0-20210528114334-82958018845c // indirect
go4.org/intern v0.0.0-20210108033219-3eb7198706b2 // indirect
go4.org/unsafe/assume-no-moving-gc v0.0.0-20201222180813-1025295fd063 // indirect
golang.org/x/text v0.3.6 // indirect golang.org/x/text v0.3.6 // indirect
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect

8
go.sum
View file

@ -186,7 +186,6 @@ github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZ
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dvyukov/go-fuzz v0.0.0-20210103155950-6a8e9d1f2415/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
@ -601,11 +600,6 @@ go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go4.org/intern v0.0.0-20210108033219-3eb7198706b2 h1:VFTf+jjIgsldaz/Mr00VaCSswHJrI2hIjQygE/W4IMg=
go4.org/intern v0.0.0-20210108033219-3eb7198706b2/go.mod h1:vLqJ+12kCw61iCWsPto0EOHhBS+o4rO5VIucbc9g2Cc=
go4.org/unsafe/assume-no-moving-gc v0.0.0-20201222175341-b30ae309168e/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E=
go4.org/unsafe/assume-no-moving-gc v0.0.0-20201222180813-1025295fd063 h1:1tk03FUNpulq2cuWpXZWj649rwJpk0d20rxWiopKRmc=
go4.org/unsafe/assume-no-moving-gc v0.0.0-20201222180813-1025295fd063/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@ -1025,8 +1019,6 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.1.1/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= honnef.co/go/tools v0.1.1/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las=
inet.af/netaddr v0.0.0-20210903134321-85fa6c94624e h1:tvgqez5ZQoBBiBAGNU/fmJy247yB/7++kcLOEoMYup0=
inet.af/netaddr v0.0.0-20210903134321-85fa6c94624e/go.mod h1:z0nx+Dh+7N7CC8V5ayHtHGpZpxLQZZxkIaaz6HN65Ls=
k8s.io/api v0.16.13/go.mod h1:QWu8UWSTiuQZMMeYjwLs6ILu5O74qKSJ0c+4vrchDxs= k8s.io/api v0.16.13/go.mod h1:QWu8UWSTiuQZMMeYjwLs6ILu5O74qKSJ0c+4vrchDxs=
k8s.io/apimachinery v0.16.13/go.mod h1:4HMHS3mDHtVttspuuhrJ1GGr/0S9B6iWYWZ57KnnZqQ= k8s.io/apimachinery v0.16.13/go.mod h1:4HMHS3mDHtVttspuuhrJ1GGr/0S9B6iWYWZ57KnnZqQ=
k8s.io/apimachinery v0.16.14-rc.0/go.mod h1:4HMHS3mDHtVttspuuhrJ1GGr/0S9B6iWYWZ57KnnZqQ= k8s.io/apimachinery v0.16.14-rc.0/go.mod h1:4HMHS3mDHtVttspuuhrJ1GGr/0S9B6iWYWZ57KnnZqQ=

View file

@ -69,9 +69,6 @@ func ParseWithPath(path string) (*config.Config, error) {
// ParseWithBytes config with buffer // ParseWithBytes config with buffer
func ParseWithBytes(buf []byte) (*config.Config, error) { func ParseWithBytes(buf []byte) (*config.Config, error) {
mux.Lock()
defer mux.Unlock()
return config.Parse(buf) return config.Parse(buf)
} }

View file

@ -2,7 +2,6 @@ package router
import ( import (
"fmt" "fmt"
"net"
"strings" "strings"
"github.com/Dreamacro/clash/rule/geodata/strmatcher" "github.com/Dreamacro/clash/rule/geodata/strmatcher"
@ -69,44 +68,3 @@ func NewDomainMatcher(domains []*Domain) (*DomainMatcher, error) {
func (m *DomainMatcher) ApplyDomain(domain string) bool { func (m *DomainMatcher) ApplyDomain(domain string) bool {
return len(m.matchers.Match(strings.ToLower(domain))) > 0 return len(m.matchers.Match(strings.ToLower(domain))) > 0
} }
type MultiGeoIPMatcher struct {
matchers []*GeoIPMatcher
}
func NewMultiGeoIPMatcher(geoips []*GeoIP) (*MultiGeoIPMatcher, error) {
var matchers []*GeoIPMatcher
for _, geoip := range geoips {
matcher, err := globalGeoIPContainer.Add(geoip)
if err != nil {
return nil, err
}
matchers = append(matchers, matcher)
}
matcher := &MultiGeoIPMatcher{
matchers: matchers,
}
return matcher, nil
}
func (m *MultiGeoIPMatcher) ApplyIp(ip net.IP) bool {
for _, matcher := range m.matchers {
if matcher.Match(ip) {
return true
}
}
return false
}
func NewGeoIPMatcher(geoip *GeoIP) (*GeoIPMatcher, error) {
matcher, err := globalGeoIPContainer.Add(geoip)
if err != nil {
return nil, err
}
return matcher, nil
}

View file

@ -1,110 +0,0 @@
package router
import (
"fmt"
"net"
"inet.af/netaddr"
)
type GeoIPMatcher struct {
countryCode string
reverseMatch bool
ip4 *netaddr.IPSet
ip6 *netaddr.IPSet
}
func (m *GeoIPMatcher) Init(cidrs []*CIDR) error {
var builder4, builder6 netaddr.IPSetBuilder
for _, cidr := range cidrs {
netaddrIP, ok := netaddr.FromStdIP(net.IP(cidr.GetIp()))
if !ok {
return fmt.Errorf("invalid IP address %v", cidr)
}
ipPrefix := netaddr.IPPrefixFrom(netaddrIP, uint8(cidr.GetPrefix()))
switch {
case netaddrIP.Is4():
builder4.AddPrefix(ipPrefix)
case netaddrIP.Is6():
builder6.AddPrefix(ipPrefix)
}
}
var err error
m.ip4, err = builder4.IPSet()
if err != nil {
return err
}
m.ip6, err = builder6.IPSet()
if err != nil {
return err
}
return nil
}
func (m *GeoIPMatcher) SetReverseMatch(isReverseMatch bool) {
m.reverseMatch = isReverseMatch
}
func (m *GeoIPMatcher) match4(ip net.IP) bool {
nip, ok := netaddr.FromStdIP(ip)
if !ok {
return false
}
return m.ip4.Contains(nip)
}
func (m *GeoIPMatcher) match6(ip net.IP) bool {
nip, ok := netaddr.FromStdIP(ip)
if !ok {
return false
}
return m.ip6.Contains(nip)
}
// Match returns true if the given ip is included by the GeoIP.
func (m *GeoIPMatcher) Match(ip net.IP) bool {
isMatched := false
switch len(ip) {
case net.IPv4len:
isMatched = m.match4(ip)
case net.IPv6len:
isMatched = m.match6(ip)
}
if m.reverseMatch {
return !isMatched
}
return isMatched
}
// GeoIPMatcherContainer is a container for GeoIPMatchers. It keeps unique copies of GeoIPMatcher by country code.
type GeoIPMatcherContainer struct {
matchers []*GeoIPMatcher
}
// Add adds a new GeoIP set into the container.
// If the country code of GeoIP is not empty, GeoIPMatcherContainer will try to find an existing one, instead of adding a new one.
func (c *GeoIPMatcherContainer) Add(geoip *GeoIP) (*GeoIPMatcher, error) {
if geoip.CountryCode != "" {
for _, m := range c.matchers {
if m.countryCode == geoip.CountryCode && m.reverseMatch == geoip.ReverseMatch {
return m, nil
}
}
}
m := &GeoIPMatcher{
countryCode: geoip.CountryCode,
reverseMatch: geoip.ReverseMatch,
}
if err := m.Init(geoip.Cidr); err != nil {
return nil, err
}
if geoip.CountryCode != "" {
c.matchers = append(c.matchers, m)
}
return m, nil
}
var globalGeoIPContainer GeoIPMatcherContainer

View file

@ -5,9 +5,6 @@ import (
"github.com/Dreamacro/clash/component/mmdb" "github.com/Dreamacro/clash/component/mmdb"
C "github.com/Dreamacro/clash/constant" C "github.com/Dreamacro/clash/constant"
//"github.com/Dreamacro/clash/rule/geodata"
//"github.com/Dreamacro/clash/rule/geodata/router"
//_ "github.com/Dreamacro/clash/rule/geodata/standard"
) )
type GEOIP struct { type GEOIP struct {
@ -15,7 +12,6 @@ type GEOIP struct {
adapter string adapter string
noResolveIP bool noResolveIP bool
ruleExtra *C.RuleExtra ruleExtra *C.RuleExtra
//geoIPMatcher *router.GeoIPMatcher
} }
func (g *GEOIP) RuleType() C.RuleType { func (g *GEOIP) RuleType() C.RuleType {
@ -56,38 +52,11 @@ func (g *GEOIP) GetCountry() string {
} }
func NewGEOIP(country string, adapter string, noResolveIP bool, ruleExtra *C.RuleExtra) (*GEOIP, error) { func NewGEOIP(country string, adapter string, noResolveIP bool, ruleExtra *C.RuleExtra) (*GEOIP, error) {
//geoLoaderName := "standard"
////geoLoaderName := "memconservative"
//geoLoader, err := geodata.GetGeoDataLoader(geoLoaderName)
//if err != nil {
// return nil, fmt.Errorf("load GeoIP data error, %s", err.Error())
//}
//
//records, err := geoLoader.LoadGeoIP(strings.ReplaceAll(country, "!", ""))
//if err != nil {
// return nil, fmt.Errorf("load GeoIP data error, %s", err.Error())
//}
//
//geoIP := &router.GeoIP{
// CountryCode: country,
// Cidr: records,
// ReverseMatch: strings.Contains(country, "!"),
//}
//
//geoIPMatcher, err := router.NewGeoIPMatcher(geoIP)
//
//if err != nil {
// return nil, fmt.Errorf("load GeoIP data error, %s", err.Error())
//}
//
//log.Infoln("Start initial GeoIP rule %s => %s, records: %d, reverse match: %v", country, adapter, len(records), geoIP.ReverseMatch)
geoip := &GEOIP{ geoip := &GEOIP{
country: country, country: country,
adapter: adapter, adapter: adapter,
noResolveIP: noResolveIP, noResolveIP: noResolveIP,
ruleExtra: ruleExtra, ruleExtra: ruleExtra,
//geoIPMatcher: geoIPMatcher,
} }
return geoip, nil return geoip, nil