feat: tun support auto-redirect, route-address-set and route-exclude-address-set

This commit is contained in:
wwqgtxx
2024-06-17 22:04:51 +08:00
parent 0738e18100
commit 09be5cbc99
28 changed files with 745 additions and 247 deletions

View File

@@ -4,6 +4,8 @@ import (
"github.com/metacubex/mihomo/component/cidr"
C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/log"
"go4.org/netipx"
)
type ipcidrStrategy struct {
@@ -52,6 +54,10 @@ func (i *ipcidrStrategy) FinishInsert() {
i.cidrSet.Merge()
}
func (i *ipcidrStrategy) ToIpCidr() *netipx.IPSet {
return i.cidrSet.ToIPSet()
}
func NewIPCidrStrategy() *ipcidrStrategy {
return &ipcidrStrategy{}
}

View File

@@ -12,8 +12,8 @@ type UpdatableProvider interface {
UpdatedAt() time.Time
}
func (f *ruleSetProvider) UpdatedAt() time.Time {
return f.Fetcher.UpdatedAt
func (rp *ruleSetProvider) UpdatedAt() time.Time {
return rp.Fetcher.UpdatedAt
}
func (rp *ruleSetProvider) Close() error {

View File

@@ -15,12 +15,14 @@ import (
P "github.com/metacubex/mihomo/constant/provider"
)
var (
ruleProviders = map[string]P.RuleProvider{}
)
var tunnel P.Tunnel
func SetTunnel(t P.Tunnel) {
tunnel = t
}
type ruleSetProvider struct {
*resource.Fetcher[any]
*resource.Fetcher[ruleStrategy]
behavior P.RuleBehavior
format P.RuleFormat
strategy ruleStrategy
@@ -49,16 +51,6 @@ type ruleStrategy interface {
FinishInsert()
}
func RuleProviders() map[string]P.RuleProvider {
return ruleProviders
}
func SetRuleProvider(ruleProvider P.RuleProvider) {
if ruleProvider != nil {
ruleProviders[(ruleProvider).Name()] = ruleProvider
}
}
func (rp *ruleSetProvider) Type() P.ProviderType {
return P.Rule
}
@@ -99,8 +91,8 @@ func (rp *ruleSetProvider) ShouldFindProcess() bool {
return rp.strategy.ShouldFindProcess()
}
func (rp *ruleSetProvider) AsRule(adaptor string) C.Rule {
panic("implement me")
func (rp *ruleSetProvider) Strategy() any {
return rp.strategy
}
func (rp *ruleSetProvider) MarshalJSON() ([]byte, error) {
@@ -123,13 +115,15 @@ func NewRuleSetProvider(name string, behavior P.RuleBehavior, format P.RuleForma
format: format,
}
onUpdate := func(elm interface{}) {
strategy := elm.(ruleStrategy)
onUpdate := func(strategy ruleStrategy) {
rp.strategy = strategy
tunnel.RuleUpdateCallback().Emit(rp)
}
rp.strategy = newStrategy(behavior, parse)
rp.Fetcher = resource.NewFetcher(name, interval, vehicle, func(bytes []byte) (any, error) { return rulesParse(bytes, newStrategy(behavior, parse), format) }, onUpdate)
rp.Fetcher = resource.NewFetcher(name, interval, vehicle, func(bytes []byte) (ruleStrategy, error) {
return rulesParse(bytes, newStrategy(behavior, parse), format)
}, onUpdate)
wrapper := &RuleSetProvider{
rp,
@@ -158,7 +152,7 @@ func newStrategy(behavior P.RuleBehavior, parse func(tp, payload, target string,
var ErrNoPayload = errors.New("file must have a `payload` field")
func rulesParse(buf []byte, strategy ruleStrategy, format P.RuleFormat) (any, error) {
func rulesParse(buf []byte, strategy ruleStrategy, format P.RuleFormat) (ruleStrategy, error) {
strategy.Reset()
schema := &RulePayload{}

View File

@@ -1,7 +1,6 @@
package provider
import (
"fmt"
C "github.com/metacubex/mihomo/constant"
P "github.com/metacubex/mihomo/constant/provider"
"github.com/metacubex/mihomo/rules/common"
@@ -11,13 +10,18 @@ type RuleSet struct {
*common.Base
ruleProviderName string
adapter string
ruleProvider P.RuleProvider
noResolveIP bool
shouldFindProcess bool
}
func (rs *RuleSet) ShouldFindProcess() bool {
return rs.shouldFindProcess || rs.getProviders().ShouldFindProcess()
if rs.shouldFindProcess {
return true
}
if provider, ok := rs.getProvider(); ok {
return provider.ShouldFindProcess()
}
return false
}
func (rs *RuleSet) RuleType() C.RuleType {
@@ -25,7 +29,10 @@ func (rs *RuleSet) RuleType() C.RuleType {
}
func (rs *RuleSet) Match(metadata *C.Metadata) (bool, string) {
return rs.getProviders().Match(metadata), rs.adapter
if provider, ok := rs.getProvider(); ok {
return provider.Match(metadata), rs.adapter
}
return false, ""
}
func (rs *RuleSet) Adapter() string {
@@ -33,31 +40,37 @@ func (rs *RuleSet) Adapter() string {
}
func (rs *RuleSet) Payload() string {
return rs.getProviders().Name()
if provider, ok := rs.getProvider(); ok {
return provider.Name()
}
return ""
}
func (rs *RuleSet) ShouldResolveIP() bool {
return !rs.noResolveIP && rs.getProviders().ShouldResolveIP()
}
func (rs *RuleSet) getProviders() P.RuleProvider {
if rs.ruleProvider == nil {
rp := RuleProviders()[rs.ruleProviderName]
rs.ruleProvider = rp
if rs.noResolveIP {
return false
}
if provider, ok := rs.getProvider(); ok {
return provider.ShouldResolveIP()
}
return false
}
return rs.ruleProvider
func (rs *RuleSet) ProviderNames() []string {
return []string{rs.ruleProviderName}
}
func (rs *RuleSet) getProvider() (P.RuleProvider, bool) {
pp, ok := tunnel.RuleProviders()[rs.ruleProviderName]
return pp, ok
}
func NewRuleSet(ruleProviderName string, adapter string, noResolveIP bool) (*RuleSet, error) {
rp, ok := RuleProviders()[ruleProviderName]
if !ok {
return nil, fmt.Errorf("rule set %s not found", ruleProviderName)
}
return &RuleSet{
rs := &RuleSet{
Base: &common.Base{},
ruleProviderName: ruleProviderName,
adapter: adapter,
ruleProvider: rp,
noResolveIP: noResolveIP,
}, nil
}
return rs, nil
}