Merge branch 'Dev' into Feature
# Conflicts: # Makefile
This commit is contained in:
commit
cdc8baf44e
8 changed files with 114 additions and 74 deletions
44
.github/workflows/dev.yml
vendored
Normal file
44
.github/workflows/dev.yml
vendored
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
name: Dev
|
||||||
|
on: [push]
|
||||||
|
jobs:
|
||||||
|
dev-build:
|
||||||
|
if: ${{ !contains(github.event.head_commit.message, '[Skip CI]') }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Get latest go version
|
||||||
|
id: version
|
||||||
|
run: |
|
||||||
|
echo ::set-output name=go_version::$(curl -s https://raw.githubusercontent.com/actions/go-versions/main/versions-manifest.json | grep -oE '"version": "[0-9]{1}.[0-9]{1,}(.[0-9]{1,})?"' | head -1 | cut -d':' -f2 | sed 's/ //g; s/"//g')
|
||||||
|
- name: Setup Go
|
||||||
|
uses: actions/setup-go@v2
|
||||||
|
with:
|
||||||
|
go-version: ${{ steps.version.outputs.go_version }}
|
||||||
|
|
||||||
|
- name: Check out code into the Go module directory
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Cache go module
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: ~/go/pkg/mod
|
||||||
|
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-go-
|
||||||
|
# - name: Get dependencies, run test
|
||||||
|
# run: |
|
||||||
|
# go test ./...
|
||||||
|
- name: Build
|
||||||
|
if: success()
|
||||||
|
env:
|
||||||
|
NAME: Clash.Meta
|
||||||
|
BINDIR: bin
|
||||||
|
run: make -j releases
|
||||||
|
|
||||||
|
- name: Upload Dev
|
||||||
|
uses: softprops/action-gh-release@v1
|
||||||
|
if: ${{ env.GIT_BRANCH != 'Meta' && success() }}
|
||||||
|
with:
|
||||||
|
tag_name: develop
|
||||||
|
files: bin/*
|
||||||
|
prerelease: true
|
||||||
|
|
|
@ -26,10 +26,20 @@ func NewInner(conn net.Conn, dst string, host string) *context.ConnContext {
|
||||||
metadata.NetWork = C.TCP
|
metadata.NetWork = C.TCP
|
||||||
metadata.Type = C.INNER
|
metadata.Type = C.INNER
|
||||||
metadata.DNSMode = C.DNSMapping
|
metadata.DNSMode = C.DNSMapping
|
||||||
metadata.AddrType = C.AtypDomainName
|
|
||||||
metadata.Host = host
|
metadata.Host = host
|
||||||
if _, port, err := parseAddr(dst); err == nil {
|
metadata.AddrType = C.AtypDomainName
|
||||||
|
metadata.Process = C.ClashName
|
||||||
|
if ip, port, err := parseAddr(dst); err == nil {
|
||||||
metadata.DstPort = port
|
metadata.DstPort = port
|
||||||
|
if host == "" {
|
||||||
|
metadata.DstIP = ip
|
||||||
|
if ip.To4() == nil {
|
||||||
|
metadata.AddrType = C.AtypIPv6
|
||||||
|
} else {
|
||||||
|
metadata.AddrType = C.AtypIPv4
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return context.NewConnContext(conn, metadata)
|
return context.NewConnContext(conn, metadata)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,4 +5,5 @@ var (
|
||||||
Version = "1.9.0"
|
Version = "1.9.0"
|
||||||
BuildTime = "unknown time"
|
BuildTime = "unknown time"
|
||||||
AutoIptables string
|
AutoIptables string
|
||||||
|
ClashName = "Clash.Meta"
|
||||||
)
|
)
|
||||||
|
|
|
@ -35,26 +35,28 @@ func (ps *Process) Match(metadata *C.Metadata) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
key := fmt.Sprintf("%s:%s:%s", metadata.NetWork.String(), metadata.SrcIP.String(), metadata.SrcPort)
|
key := fmt.Sprintf("%s:%s:%s", metadata.NetWork.String(), metadata.SrcIP.String(), metadata.SrcPort)
|
||||||
cached, hit := processCache.Get(key)
|
if strings.TrimSpace(metadata.Process) == "" {
|
||||||
if !hit {
|
cached, hit := processCache.Get(key)
|
||||||
srcPort, err := strconv.Atoi(metadata.SrcPort)
|
if !hit {
|
||||||
if err != nil {
|
srcPort, err := strconv.Atoi(metadata.SrcPort)
|
||||||
processCache.Set(key, "")
|
if err != nil {
|
||||||
return false
|
processCache.Set(key, "")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
name, err := process.FindProcessName(metadata.NetWork.String(), metadata.SrcIP, srcPort)
|
||||||
|
if err != nil {
|
||||||
|
log.Debugln("[Rule] find process name %s error: %s", C.Process.String(), err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
processCache.Set(key, name)
|
||||||
|
|
||||||
|
cached = name
|
||||||
}
|
}
|
||||||
|
|
||||||
name, err := process.FindProcessName(metadata.NetWork.String(), metadata.SrcIP, srcPort)
|
metadata.Process = cached.(string)
|
||||||
if err != nil {
|
|
||||||
log.Debugln("[Rule] find process name %s error: %s", C.Process.String(), err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
processCache.Set(key, name)
|
|
||||||
|
|
||||||
cached = name
|
|
||||||
}
|
}
|
||||||
|
|
||||||
metadata.Process = cached.(string)
|
|
||||||
|
|
||||||
return strings.EqualFold(metadata.Process, ps.process)
|
return strings.EqualFold(metadata.Process, ps.process)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ type AND struct {
|
||||||
|
|
||||||
func NewAND(payload string, adapter string) (*AND, error) {
|
func NewAND(payload string, adapter string) (*AND, error) {
|
||||||
and := &AND{payload: payload, adapter: adapter}
|
and := &AND{payload: payload, adapter: adapter}
|
||||||
rules, err := parseRule(payload)
|
rules, err := parseRuleByPayload(payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,63 +10,29 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func parseRule(payload string) ([]C.Rule, error) {
|
func parseRuleByPayload(payload string) ([]C.Rule, error) {
|
||||||
regex, err := regexp.Compile("\\(.*\\)")
|
regex, err := regexp.Compile("\\(.*\\)")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if regex.MatchString(payload) {
|
if regex.MatchString(payload) {
|
||||||
subRanges, err := format(payload)
|
subAllRanges, err := format(payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
rules := make([]C.Rule, 0, len(subRanges))
|
rules := make([]C.Rule, 0, len(subAllRanges))
|
||||||
|
|
||||||
|
subRanges := findSubRuleRange(payload, subAllRanges)
|
||||||
|
for _, subRange := range subRanges {
|
||||||
|
subPayload := payload[subRange.start+1 : subRange.end]
|
||||||
|
|
||||||
if len(subRanges) == 1 {
|
|
||||||
subPayload := payload[subRanges[0].start+1 : subRanges[0].end-1]
|
|
||||||
rule, err := payloadToRule(subPayload)
|
rule, err := payloadToRule(subPayload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
rules = append(rules, rule)
|
rules = append(rules, rule)
|
||||||
} else {
|
|
||||||
preStart := subRanges[0].start
|
|
||||||
preEnd := subRanges[0].end
|
|
||||||
for _, sr := range subRanges[1:] {
|
|
||||||
if containRange(sr, preStart, preEnd) && sr.start-preStart > 1 {
|
|
||||||
str := ""
|
|
||||||
if preStart+1 <= sr.start-1 {
|
|
||||||
str = strings.TrimSpace(payload[preStart+1 : sr.start-1])
|
|
||||||
}
|
|
||||||
|
|
||||||
if str == "AND" || str == "OR" || str == "NOT" {
|
|
||||||
subPayload := payload[preStart+1 : preEnd]
|
|
||||||
rule, err := payloadToRule(subPayload)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
rules = append(rules, rule)
|
|
||||||
preStart = sr.start
|
|
||||||
preEnd = sr.end
|
|
||||||
}
|
|
||||||
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
preStart = sr.start
|
|
||||||
preEnd = sr.end
|
|
||||||
|
|
||||||
subPayload := payload[sr.start+1 : sr.end]
|
|
||||||
rule, err := payloadToRule(subPayload)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
rules = append(rules, rule)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rules, nil
|
return rules, nil
|
||||||
|
@ -84,23 +50,14 @@ func payloadToRule(subPayload string) (C.Rule, error) {
|
||||||
tp := splitStr[0]
|
tp := splitStr[0]
|
||||||
payload := splitStr[1]
|
payload := splitStr[1]
|
||||||
if tp == "NOT" || tp == "OR" || tp == "AND" {
|
if tp == "NOT" || tp == "OR" || tp == "AND" {
|
||||||
return parseSubRule(tp, payload, nil)
|
return parseRule(tp, payload, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
param := strings.Split(payload, ",")
|
param := strings.Split(payload, ",")
|
||||||
return parseSubRule(tp, param[0], param[1:])
|
return parseRule(tp, param[0], param[1:])
|
||||||
}
|
}
|
||||||
|
|
||||||
func splitSubRule(subRuleStr string) (string, string, []string, error) {
|
func parseRule(tp, payload string, params []string) (C.Rule, error) {
|
||||||
typeAndRule := strings.Split(subRuleStr, ",")
|
|
||||||
if len(typeAndRule) < 2 {
|
|
||||||
return "", "", nil, fmt.Errorf("format error:[%s]", typeAndRule)
|
|
||||||
}
|
|
||||||
|
|
||||||
return strings.TrimSpace(typeAndRule[0]), strings.TrimSpace(typeAndRule[1]), typeAndRule[2:], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseSubRule(tp, payload string, params []string) (C.Rule, error) {
|
|
||||||
var (
|
var (
|
||||||
parseErr error
|
parseErr error
|
||||||
parsed C.Rule
|
parsed C.Rule
|
||||||
|
@ -183,3 +140,29 @@ func format(payload string) ([]Range, error) {
|
||||||
|
|
||||||
return sortResult, nil
|
return sortResult, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func findSubRuleRange(payload string, ruleRanges []Range) []Range {
|
||||||
|
payloadLen := len(payload)
|
||||||
|
subRuleRange := make([]Range, 0)
|
||||||
|
for _, rr := range ruleRanges {
|
||||||
|
if rr.start == 0 && rr.end == payloadLen-1 {
|
||||||
|
// 最大范围跳过
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
containInSub := false
|
||||||
|
for _, r := range subRuleRange {
|
||||||
|
if containRange(rr, r.start, r.end) {
|
||||||
|
// The subRuleRange contains a range of rr, which is the next level node of the tree
|
||||||
|
containInSub = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !containInSub {
|
||||||
|
subRuleRange = append(subRuleRange, rr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return subRuleRange
|
||||||
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ type NOT struct {
|
||||||
|
|
||||||
func NewNOT(payload string, adapter string) (*NOT, error) {
|
func NewNOT(payload string, adapter string) (*NOT, error) {
|
||||||
not := &NOT{payload: payload, adapter: adapter}
|
not := &NOT{payload: payload, adapter: adapter}
|
||||||
rule, err := parseRule(payload)
|
rule, err := parseRuleByPayload(payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ func (or *OR) RuleExtra() *C.RuleExtra {
|
||||||
|
|
||||||
func NewOR(payload string, adapter string) (*OR, error) {
|
func NewOR(payload string, adapter string) (*OR, error) {
|
||||||
or := &OR{payload: payload, adapter: adapter}
|
or := &OR{payload: payload, adapter: adapter}
|
||||||
rules, err := parseRule(payload)
|
rules, err := parseRuleByPayload(payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue