mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-05-23 04:39:52 +03:00
Improve rule actions
This commit is contained in:
@@ -5,9 +5,11 @@ import (
|
||||
"net/netip"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/common/dialer"
|
||||
"github.com/sagernet/sing-box/common/sniff"
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
@@ -17,19 +19,42 @@ import (
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
F "github.com/sagernet/sing/common/format"
|
||||
"github.com/sagernet/sing/common/logger"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
)
|
||||
|
||||
func NewRuleAction(logger logger.ContextLogger, action option.RuleAction) (adapter.RuleAction, error) {
|
||||
func NewRuleAction(router adapter.Router, logger logger.ContextLogger, action option.RuleAction) (adapter.RuleAction, error) {
|
||||
switch action.Action {
|
||||
case "":
|
||||
return nil, nil
|
||||
case C.RuleActionTypeRoute:
|
||||
return &RuleActionRoute{
|
||||
Outbound: action.RouteOptions.Outbound,
|
||||
UDPDisableDomainUnmapping: action.RouteOptions.UDPDisableDomainUnmapping,
|
||||
Outbound: action.RouteOptions.Outbound,
|
||||
}, nil
|
||||
case C.RuleActionTypeRouteOptions:
|
||||
return &RuleActionRouteOptions{
|
||||
UDPDisableDomainUnmapping: action.RouteOptionsOptions.UDPDisableDomainUnmapping,
|
||||
UDPConnect: action.RouteOptionsOptions.UDPConnect,
|
||||
}, nil
|
||||
case C.RuleActionTypeDirect:
|
||||
directDialer, err := dialer.New(router, option.DialerOptions(action.DirectOptions))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var description string
|
||||
descriptions := action.DirectOptions.Descriptions()
|
||||
switch len(descriptions) {
|
||||
case 0:
|
||||
case 1:
|
||||
description = F.ToString("(", descriptions[0], ")")
|
||||
case 2:
|
||||
description = F.ToString("(", descriptions[0], ",", descriptions[1], ")")
|
||||
default:
|
||||
description = F.ToString("(", descriptions[0], ",", descriptions[1], ",...)")
|
||||
}
|
||||
return &RuleActionDirect{
|
||||
Dialer: directDialer,
|
||||
description: description,
|
||||
}, nil
|
||||
case C.RuleActionTypeReturn:
|
||||
return &RuleActionReturn{}, nil
|
||||
case C.RuleActionTypeReject:
|
||||
return &RuleActionReject{
|
||||
Method: action.RejectOptions.Method,
|
||||
@@ -56,6 +81,8 @@ func NewRuleAction(logger logger.ContextLogger, action option.RuleAction) (adapt
|
||||
|
||||
func NewDNSRuleAction(logger logger.ContextLogger, action option.DNSRuleAction) adapter.RuleAction {
|
||||
switch action.Action {
|
||||
case "":
|
||||
return nil
|
||||
case C.RuleActionTypeRoute:
|
||||
return &RuleActionDNSRoute{
|
||||
Server: action.RouteOptions.Server,
|
||||
@@ -63,8 +90,12 @@ func NewDNSRuleAction(logger logger.ContextLogger, action option.DNSRuleAction)
|
||||
RewriteTTL: action.RouteOptions.RewriteTTL,
|
||||
ClientSubnet: action.RouteOptions.ClientSubnet.Build(),
|
||||
}
|
||||
case C.RuleActionTypeReturn:
|
||||
return &RuleActionReturn{}
|
||||
case C.RuleActionTypeRouteOptions:
|
||||
return &RuleActionDNSRouteOptions{
|
||||
DisableCache: action.RouteOptionsOptions.DisableCache,
|
||||
RewriteTTL: action.RouteOptionsOptions.RewriteTTL,
|
||||
ClientSubnet: action.RouteOptionsOptions.ClientSubnet.Build(),
|
||||
}
|
||||
case C.RuleActionTypeReject:
|
||||
return &RuleActionReject{
|
||||
Method: action.RejectOptions.Method,
|
||||
@@ -77,8 +108,7 @@ func NewDNSRuleAction(logger logger.ContextLogger, action option.DNSRuleAction)
|
||||
}
|
||||
|
||||
type RuleActionRoute struct {
|
||||
Outbound string
|
||||
UDPDisableDomainUnmapping bool
|
||||
Outbound string
|
||||
}
|
||||
|
||||
func (r *RuleActionRoute) Type() string {
|
||||
@@ -89,6 +119,26 @@ func (r *RuleActionRoute) String() string {
|
||||
return F.ToString("route(", r.Outbound, ")")
|
||||
}
|
||||
|
||||
type RuleActionRouteOptions struct {
|
||||
UDPDisableDomainUnmapping bool
|
||||
UDPConnect bool
|
||||
}
|
||||
|
||||
func (r *RuleActionRouteOptions) Type() string {
|
||||
return C.RuleActionTypeRouteOptions
|
||||
}
|
||||
|
||||
func (r *RuleActionRouteOptions) String() string {
|
||||
var descriptions []string
|
||||
if r.UDPDisableDomainUnmapping {
|
||||
descriptions = append(descriptions, "udp-disable-domain-unmapping")
|
||||
}
|
||||
if r.UDPConnect {
|
||||
descriptions = append(descriptions, "udp-connect")
|
||||
}
|
||||
return F.ToString("route-options(", strings.Join(descriptions, ","), ")")
|
||||
}
|
||||
|
||||
type RuleActionDNSRoute struct {
|
||||
Server string
|
||||
DisableCache bool
|
||||
@@ -104,14 +154,41 @@ func (r *RuleActionDNSRoute) String() string {
|
||||
return F.ToString("route(", r.Server, ")")
|
||||
}
|
||||
|
||||
type RuleActionReturn struct{}
|
||||
|
||||
func (r *RuleActionReturn) Type() string {
|
||||
return C.RuleActionTypeReturn
|
||||
type RuleActionDNSRouteOptions struct {
|
||||
DisableCache bool
|
||||
RewriteTTL *uint32
|
||||
ClientSubnet netip.Prefix
|
||||
}
|
||||
|
||||
func (r *RuleActionReturn) String() string {
|
||||
return "return"
|
||||
func (r *RuleActionDNSRouteOptions) Type() string {
|
||||
return C.RuleActionTypeRouteOptions
|
||||
}
|
||||
|
||||
func (r *RuleActionDNSRouteOptions) String() string {
|
||||
var descriptions []string
|
||||
if r.DisableCache {
|
||||
descriptions = append(descriptions, "disable-cache")
|
||||
}
|
||||
if r.RewriteTTL != nil {
|
||||
descriptions = append(descriptions, F.ToString("rewrite-ttl(", *r.RewriteTTL, ")"))
|
||||
}
|
||||
if r.ClientSubnet.IsValid() {
|
||||
descriptions = append(descriptions, F.ToString("client-subnet(", r.ClientSubnet, ")"))
|
||||
}
|
||||
return F.ToString("route-options(", strings.Join(descriptions, ","), ")")
|
||||
}
|
||||
|
||||
type RuleActionDirect struct {
|
||||
Dialer N.Dialer
|
||||
description string
|
||||
}
|
||||
|
||||
func (r *RuleActionDirect) Type() string {
|
||||
return C.RuleActionTypeDirect
|
||||
}
|
||||
|
||||
func (r *RuleActionDirect) String() string {
|
||||
return "direct" + r.description
|
||||
}
|
||||
|
||||
type RuleActionReject struct {
|
||||
@@ -137,7 +214,7 @@ func (r *RuleActionReject) Error(ctx context.Context) error {
|
||||
var returnErr error
|
||||
switch r.Method {
|
||||
case C.RuleActionRejectMethodDefault:
|
||||
returnErr = unix.ECONNREFUSED
|
||||
returnErr = syscall.ECONNREFUSED
|
||||
case C.RuleActionRejectMethodDrop:
|
||||
return tun.ErrDrop
|
||||
default:
|
||||
|
||||
@@ -52,7 +52,7 @@ type RuleItem interface {
|
||||
}
|
||||
|
||||
func NewDefaultRule(ctx context.Context, router adapter.Router, logger log.ContextLogger, options option.DefaultRule) (*DefaultRule, error) {
|
||||
action, err := NewRuleAction(logger, options.RuleAction)
|
||||
action, err := NewRuleAction(router, logger, options.RuleAction)
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "action")
|
||||
}
|
||||
@@ -254,7 +254,7 @@ type LogicalRule struct {
|
||||
}
|
||||
|
||||
func NewLogicalRule(ctx context.Context, router adapter.Router, logger log.ContextLogger, options option.LogicalRule) (*LogicalRule, error) {
|
||||
action, err := NewRuleAction(logger, options.RuleAction)
|
||||
action, err := NewRuleAction(router, logger, options.RuleAction)
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "action")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user