Chore: script built
This commit is contained in:
parent
cbea46b0c8
commit
63d07db4bf
17 changed files with 139 additions and 249 deletions
27
.github/workflows/go.yml
vendored
27
.github/workflows/go.yml
vendored
|
@ -29,6 +29,26 @@ jobs:
|
|||
|
||||
- name: Get dependencies, run test and static check
|
||||
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 vet ./...
|
||||
go install honnef.co/go/tools/cmd/staticcheck@latest
|
||||
|
@ -41,6 +61,8 @@ jobs:
|
|||
- name: SSH connection to Actions
|
||||
uses: P3TERX/ssh2actions@v1.0.0
|
||||
if: github.actor == github.repository_owner && contains(github.event.head_commit.message, '[ssh]')
|
||||
env:
|
||||
SSH_PASSWORD: ${{ secrets.ADAWADLHIOH }}
|
||||
|
||||
- name: Build
|
||||
#if: startsWith(github.ref, 'refs/tags/')
|
||||
|
@ -48,11 +70,12 @@ jobs:
|
|||
NAME: clash
|
||||
BINDIR: bin
|
||||
run: |
|
||||
make cleancache && make -j releases
|
||||
make -j releases
|
||||
|
||||
- name: Prepare upload
|
||||
if: startsWith(github.ref, 'refs/tags/') == false
|
||||
run: |
|
||||
rm -rf bin/python/
|
||||
echo "FILE_DATE=_$(date +"%Y%m%d%H%M")" >> $GITHUB_ENV
|
||||
echo "FILE_SHA=$(git describe --tags --always 2>/dev/null)" >> $GITHUB_ENV
|
||||
|
||||
|
@ -83,6 +106,6 @@ jobs:
|
|||
with:
|
||||
keep_latest: 1
|
||||
delete_tags: true
|
||||
delete_tag_pattern: premium
|
||||
delete_tag_pattern: plus-pro
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
|
35
Makefile
35
Makefile
|
@ -16,27 +16,29 @@ STATIC_LDFLAGS='-X "github.com/Dreamacro/clash/constant.Version=$(VERSION)" \
|
|||
-w -s -buildid='
|
||||
|
||||
PLATFORM_LIST = \
|
||||
darwin-10.12-amd64 \
|
||||
darwin-10.15-arm64 \
|
||||
linux-386 \
|
||||
darwin-amd64 \
|
||||
darwin-arm64 \
|
||||
linux-amd64 \
|
||||
linux-arm64
|
||||
# linux-386
|
||||
|
||||
WINDOWS_ARCH_LIST = \
|
||||
windows-4.0-amd64 \
|
||||
windows-4.0-386
|
||||
windows-amd64 \
|
||||
windows-386
|
||||
# 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:
|
||||
$(GOBUILD) -ldflags $(RELEASE_LDFLAGS) -o $(BINDIR)/$(NAME)-$@
|
||||
$(GOBUILD) -ldflags $(RELEASE_LDFLAGS) -tags build_local -o $(BINDIR)/$(NAME)-$@
|
||||
|
||||
darwin-10.12-amd64:
|
||||
$(XGOCMD) -dest=$(BINDIR) -out=$(NAME) -trimpath=true -ldflags=$(RELEASE_LDFLAGS) -targets=darwin-10.12/amd64 $(BUILD_PACKAGE)
|
||||
darwin-amd64:
|
||||
$(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:
|
||||
$(XGOCMD) -dest=$(BINDIR) -out=$(NAME) -trimpath=true -ldflags=$(RELEASE_LDFLAGS) -targets=darwin-10.15/arm64 $(BUILD_PACKAGE)
|
||||
darwin-arm64:
|
||||
$(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:
|
||||
$(XGOCMD) -dest=$(BINDIR) -out=$(NAME) -trimpath=true -ldflags=$(STATIC_LDFLAGS) -targets=linux/386 $(BUILD_PACKAGE)
|
||||
|
@ -48,14 +50,17 @@ linux-amd64:
|
|||
linux-arm64:
|
||||
$(XGOCMD) -dest=$(BINDIR) -out=$(NAME) -trimpath=true -ldflags=$(STATIC_LDFLAGS) -targets=linux/arm64 $(BUILD_PACKAGE)
|
||||
|
||||
windows-4.0-386:
|
||||
$(XGOCMD) -dest=$(BINDIR) -out=$(NAME) -trimpath=true -ldflags=$(RELEASE_LDFLAGS) -targets=windows-4.0/386 $(BUILD_PACKAGE)
|
||||
windows-386:
|
||||
$(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:
|
||||
$(XGOCMD) -dest=$(BINDIR) -out=$(NAME) -trimpath=true -ldflags=$(RELEASE_LDFLAGS) -targets=windows-4.0/amd64 $(BUILD_PACKAGE)
|
||||
windows-amd64:
|
||||
$(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:
|
||||
# $(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))
|
||||
zip_releases=$(addsuffix .zip, $(WINDOWS_ARCH_LIST))
|
||||
|
|
44
README.md
44
README.md
|
@ -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'
|
||||
|
||||
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,REJECT,udp
|
||||
|
||||
# multiport condition for rules SRC-PORT and DST-PORT
|
||||
- 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
|
||||
- GEOSITE,category-ads-all,REJECT
|
||||
- GEOSITE,icloud@cn,DIRECT
|
||||
|
@ -106,7 +106,7 @@ Script enables users to programmatically select a policy for the packets with mo
|
|||
mode: script
|
||||
|
||||
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,youtube,Whatever
|
||||
- GEOSITE,geolocation-cn,Whatever
|
||||
|
@ -138,7 +138,7 @@ script:
|
|||
|
||||
if ctx.rule_providers["geosite:geolocation-cn"].match(metadata):
|
||||
ctx.log('[Script] domain %s matched geolocation-cn' % host)
|
||||
return "CN"
|
||||
return "DIRECT"
|
||||
|
||||
ip = metadata["dst_ip"]
|
||||
if host != "":
|
||||
|
@ -153,23 +153,23 @@ script:
|
|||
return "Proxy" # default policy for requests which are not matched by any other script
|
||||
```
|
||||
the context and metadata
|
||||
```python
|
||||
```ts
|
||||
interface Metadata {
|
||||
type: string // socks5、http
|
||||
network: string // tcp
|
||||
host: string
|
||||
process_name: string
|
||||
src_ip: string
|
||||
src_port: int
|
||||
dst_ip: string
|
||||
dst_port: int
|
||||
type: string // socks5、http
|
||||
network: string // tcp
|
||||
host: string
|
||||
process_name: string
|
||||
src_ip: string
|
||||
src_port: int
|
||||
dst_ip: string
|
||||
dst_port: int
|
||||
}
|
||||
|
||||
interface Context {
|
||||
resolve_ip: (host: string) => string // ip string
|
||||
geoip: (ip: string) => string // country code
|
||||
log: (log: string) => void
|
||||
rule_providers: Record<string, { match: (metadata: Metadata) => boolean }>
|
||||
resolve_ip: (host: string) => string // ip string
|
||||
geoip: (ip: string) => string // country code
|
||||
log: (log: string) => void
|
||||
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.
|
||||
|
||||
Create the systemd configuration file at /etc/systemd/system/clash.service:
|
||||
```shell
|
||||
```
|
||||
[Unit]
|
||||
Description=Clash daemon, A rule-based proxy in Go.
|
||||
After=network.target
|
||||
|
@ -246,7 +246,7 @@ $ systemctl start clash
|
|||
```
|
||||
|
||||
### 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/.
|
||||
|
||||
|
|
9
component/script/build_local.go
Normal file
9
component/script/build_local.go
Normal file
|
@ -0,0 +1,9 @@
|
|||
//go:build build_local
|
||||
// +build build_local
|
||||
|
||||
package script
|
||||
|
||||
/*
|
||||
#cgo pkg-config: python3-embed
|
||||
*/
|
||||
import "C"
|
25
component/script/build_xgo.go
Normal file
25
component/script/build_xgo.go
Normal 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"
|
|
@ -37,8 +37,6 @@ void init_python(const char *path) {
|
|||
import can be deferred until the embedded script
|
||||
imports it. */
|
||||
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
|
||||
|
@ -87,6 +85,10 @@ void py_clear(PyObject *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. **/
|
||||
|
||||
resolve_ip_callback resolve_ip_callback_fn;
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
package script
|
||||
|
||||
/*
|
||||
#cgo pkg-config: python3-embed
|
||||
//#cgo pkg-config: python3
|
||||
//#cgo LDFLAGS: -lpython3
|
||||
|
||||
#include "clash_module.h"
|
||||
|
||||
extern const char *resolveIPCallbackFn(const char *host);
|
||||
|
@ -42,6 +38,7 @@ import (
|
|||
"os"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
@ -88,6 +85,7 @@ func Py_Initialize(path string) error {
|
|||
C.finalize_Python()
|
||||
}
|
||||
|
||||
path = strings.ReplaceAll(path, "\\", "/")
|
||||
cPath := C.CString(path)
|
||||
//defer C.free(unsafe.Pointer(cPath))
|
||||
|
||||
|
@ -182,6 +180,15 @@ func LoadShortcutFunction(shortcut string) (*PyObject, error) {
|
|||
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
|
||||
//return the proxy adapter name.
|
||||
func CallPyMainFunction(mtd *constant.Metadata) (string, error) {
|
||||
|
@ -226,7 +233,7 @@ func CallPyMainFunction(mtd *constant.Metadata) (string, error) {
|
|||
err := PyLastError()
|
||||
if err != nil {
|
||||
log.Errorln("[Script] script code error: %s", err.Error())
|
||||
syscall.Kill(syscall.Getpid(), syscall.SIGINT)
|
||||
killSelf()
|
||||
return "", fmt.Errorf("script code error: %w", err)
|
||||
} else {
|
||||
return "", fmt.Errorf("script code error, result: %v", rs)
|
||||
|
@ -281,7 +288,7 @@ func CallPyShortcut(fn *PyObject, mtd *constant.Metadata) (bool, error) {
|
|||
err := PyLastError()
|
||||
if err != nil {
|
||||
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)
|
||||
} else {
|
||||
return false, fmt.Errorf("script shortcut code error: result: %d", rs)
|
||||
|
@ -319,3 +326,14 @@ func NewClashPyContext(ruleProvidersName []string) error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func killSelf() {
|
||||
p, err := os.FindProcess(os.Getpid())
|
||||
|
||||
if err != nil {
|
||||
os.Exit(int(syscall.SIGINT))
|
||||
return
|
||||
}
|
||||
|
||||
p.Signal(syscall.SIGINT)
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ void set_log_callback(log_callback cb);
|
|||
|
||||
void append_inittab();
|
||||
void init_python(const char *path);
|
||||
void load_main_func();
|
||||
void finalize_Python();
|
||||
void py_clear(PyObject *obj);
|
||||
const char *py_last_error();
|
||||
|
|
|
@ -98,7 +98,7 @@ func ruleProviderCallbackFn(cProviderName *C.char, cMetadata *C.struct_Metadata)
|
|||
|
||||
rule, ok := ruleProviders[providerName]
|
||||
if !ok {
|
||||
log.Warnln("rule provider [%s] not found", providerName)
|
||||
log.Warnln("[Script] rule provider [%s] not found", providerName)
|
||||
return C.int(0)
|
||||
}
|
||||
|
||||
|
|
|
@ -475,9 +475,13 @@ time = ClashTime()
|
|||
|
||||
if err = S.Py_Initialize(C.Path.ScriptDir()); err != nil {
|
||||
return fmt.Errorf("initialized script module failure, %s", err.Error())
|
||||
} else {
|
||||
log.Infoln("Start initial script module successful")
|
||||
} else if mode == T.Script {
|
||||
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
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
|
||||
"github.com/Dreamacro/clash/component/mmdb"
|
||||
"github.com/Dreamacro/clash/component/trie"
|
||||
//_ "github.com/Dreamacro/clash/rule/geodata/standard"
|
||||
C "github.com/Dreamacro/clash/constant"
|
||||
)
|
||||
|
||||
type fallbackIPFilter interface {
|
||||
|
@ -19,7 +19,7 @@ type geoipFilter struct {
|
|||
|
||||
func (gf *geoipFilter) Match(ip net.IP) bool {
|
||||
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 {
|
||||
|
|
3
go.mod
3
go.mod
|
@ -25,7 +25,6 @@ require (
|
|||
google.golang.org/protobuf v1.27.1
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gvisor.dev/gvisor v0.0.0-20210922003438-b39716d116fd
|
||||
inet.af/netaddr v0.0.0-20210903134321-85fa6c94624e
|
||||
)
|
||||
|
||||
require (
|
||||
|
@ -34,8 +33,6 @@ require (
|
|||
github.com/oschwald/maxminddb-golang v1.8.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // 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/time v0.0.0-20191024005414-555d28b269f0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
|
||||
|
|
8
go.sum
8
go.sum
|
@ -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/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/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-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||
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.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
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-20181009213950-7c1a557ab941/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.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
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/apimachinery v0.16.13/go.mod h1:4HMHS3mDHtVttspuuhrJ1GGr/0S9B6iWYWZ57KnnZqQ=
|
||||
k8s.io/apimachinery v0.16.14-rc.0/go.mod h1:4HMHS3mDHtVttspuuhrJ1GGr/0S9B6iWYWZ57KnnZqQ=
|
||||
|
|
|
@ -69,9 +69,6 @@ func ParseWithPath(path string) (*config.Config, error) {
|
|||
|
||||
// ParseWithBytes config with buffer
|
||||
func ParseWithBytes(buf []byte) (*config.Config, error) {
|
||||
mux.Lock()
|
||||
defer mux.Unlock()
|
||||
|
||||
return config.Parse(buf)
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ package router
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
"github.com/Dreamacro/clash/rule/geodata/strmatcher"
|
||||
|
@ -69,44 +68,3 @@ func NewDomainMatcher(domains []*Domain) (*DomainMatcher, error) {
|
|||
func (m *DomainMatcher) ApplyDomain(domain string) bool {
|
||||
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
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -5,9 +5,6 @@ import (
|
|||
|
||||
"github.com/Dreamacro/clash/component/mmdb"
|
||||
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 {
|
||||
|
@ -15,7 +12,6 @@ type GEOIP struct {
|
|||
adapter string
|
||||
noResolveIP bool
|
||||
ruleExtra *C.RuleExtra
|
||||
//geoIPMatcher *router.GeoIPMatcher
|
||||
}
|
||||
|
||||
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) {
|
||||
//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{
|
||||
country: country,
|
||||
adapter: adapter,
|
||||
noResolveIP: noResolveIP,
|
||||
ruleExtra: ruleExtra,
|
||||
//geoIPMatcher: geoIPMatcher,
|
||||
}
|
||||
|
||||
return geoip, nil
|
||||
|
|
Loading…
Reference in a new issue