Add tunnel

This commit is contained in:
Shtorm
2025-07-06 18:31:06 +03:00
parent 54b373a73e
commit 3f97424224
29 changed files with 1262 additions and 10 deletions

View File

@@ -425,6 +425,9 @@ match:
Fqdn: metadata.Destination.Fqdn,
}
}
if routeOptions.OverrideTunnelDestination != "" {
metadata.TunnelDestination = routeOptions.OverrideTunnelDestination
}
if routeOptions.NetworkStrategy != nil {
metadata.NetworkStrategy = routeOptions.NetworkStrategy
}

View File

@@ -33,6 +33,7 @@ func NewRuleAction(ctx context.Context, logger logger.ContextLogger, action opti
RuleActionRouteOptions: RuleActionRouteOptions{
OverrideAddress: M.ParseSocksaddrHostPort(action.RouteOptions.OverrideAddress, 0),
OverridePort: action.RouteOptions.OverridePort,
OverrideTunnelDestination: action.RouteOptions.OverrideTunnelDestination,
NetworkStrategy: (*C.NetworkStrategy)(action.RouteOptions.NetworkStrategy),
FallbackDelay: time.Duration(action.RouteOptions.FallbackDelay),
UDPDisableDomainUnmapping: action.RouteOptions.UDPDisableDomainUnmapping,
@@ -147,6 +148,7 @@ func (r *RuleActionRoute) String() string {
type RuleActionRouteOptions struct {
OverrideAddress M.Socksaddr
OverridePort uint16
OverrideTunnelDestination string
NetworkStrategy *C.NetworkStrategy
NetworkType []C.InterfaceType
FallbackNetworkType []C.InterfaceType
@@ -168,6 +170,9 @@ func (r *RuleActionRouteOptions) String() string {
if r.OverridePort > 0 {
descriptions = append(descriptions, F.ToString("override-port=", r.OverridePort))
}
if r.OverrideTunnelDestination != "" {
descriptions = append(descriptions, F.ToString("override-tunnel-destination=", r.OverrideTunnelDestination))
}
if r.NetworkStrategy != nil {
descriptions = append(descriptions, F.ToString("network-strategy=", r.NetworkStrategy))
}

View File

@@ -189,6 +189,16 @@ func NewDefaultRule(ctx context.Context, logger log.ContextLogger, options optio
rule.destinationPortItems = append(rule.destinationPortItems, item)
rule.allItems = append(rule.allItems, item)
}
if len(options.TunnelSource) > 0 {
item := NewTunnelSourceItem(options.TunnelSource)
rule.items = append(rule.items, item)
rule.allItems = append(rule.allItems, item)
}
if len(options.TunnelDestination) > 0 {
item := NewTunnelDestinationItem(options.TunnelDestination)
rule.items = append(rule.items, item)
rule.allItems = append(rule.allItems, item)
}
if len(options.ProcessName) > 0 {
item := NewProcessItem(options.ProcessName)
rule.items = append(rule.items, item)

View File

@@ -180,6 +180,16 @@ func NewDefaultDNSRule(ctx context.Context, logger log.ContextLogger, options op
rule.destinationPortItems = append(rule.destinationPortItems, item)
rule.allItems = append(rule.allItems, item)
}
if len(options.TunnelSource) > 0 {
item := NewTunnelSourceItem(options.TunnelSource)
rule.items = append(rule.items, item)
rule.allItems = append(rule.allItems, item)
}
if len(options.TunnelDestination) > 0 {
item := NewTunnelDestinationItem(options.TunnelDestination)
rule.items = append(rule.items, item)
rule.allItems = append(rule.allItems, item)
}
if len(options.ProcessName) > 0 {
item := NewProcessItem(options.ProcessName)
rule.items = append(rule.items, item)

View File

@@ -121,6 +121,16 @@ func NewDefaultHeadlessRule(ctx context.Context, options option.DefaultHeadlessR
rule.destinationPortItems = append(rule.destinationPortItems, item)
rule.allItems = append(rule.allItems, item)
}
if len(options.TunnelSource) > 0 {
item := NewTunnelSourceItem(options.TunnelSource)
rule.items = append(rule.items, item)
rule.allItems = append(rule.allItems, item)
}
if len(options.TunnelDestination) > 0 {
item := NewTunnelDestinationItem(options.TunnelDestination)
rule.items = append(rule.items, item)
rule.allItems = append(rule.allItems, item)
}
if len(options.ProcessName) > 0 {
item := NewProcessItem(options.ProcessName)
rule.items = append(rule.items, item)

View File

@@ -0,0 +1,35 @@
package rule
import (
"strings"
"github.com/sagernet/sing-box/adapter"
F "github.com/sagernet/sing/common/format"
)
var _ RuleItem = (*TunnelDestinationItem)(nil)
type TunnelDestinationItem struct {
destinations []string
destinationMap map[string]bool
}
func NewTunnelDestinationItem(destinations []string) *TunnelDestinationItem {
rule := &TunnelDestinationItem{destinations, make(map[string]bool)}
for _, destination := range destinations {
rule.destinationMap[destination] = true
}
return rule
}
func (r *TunnelDestinationItem) Match(metadata *adapter.InboundContext) bool {
return r.destinationMap[metadata.TunnelDestination]
}
func (r *TunnelDestinationItem) String() string {
if len(r.destinations) == 1 {
return F.ToString("tunnel_destination=", r.destinations[0])
} else {
return F.ToString("tunnel_destination=[", strings.Join(r.destinations, " "), "]")
}
}

View File

@@ -0,0 +1,35 @@
package rule
import (
"strings"
"github.com/sagernet/sing-box/adapter"
F "github.com/sagernet/sing/common/format"
)
var _ RuleItem = (*TunnelSourceItem)(nil)
type TunnelSourceItem struct {
sources []string
sourceMap map[string]bool
}
func NewTunnelSourceItem(sources []string) *TunnelSourceItem {
rule := &TunnelSourceItem{sources, make(map[string]bool)}
for _, source := range sources {
rule.sourceMap[source] = true
}
return rule
}
func (r *TunnelSourceItem) Match(metadata *adapter.InboundContext) bool {
return r.sourceMap[metadata.TunnelSource]
}
func (r *TunnelSourceItem) String() string {
if len(r.sources) == 1 {
return F.ToString("tunnel_source=", r.sources[0])
} else {
return F.ToString("tunnel_source=[", strings.Join(r.sources, " "), "]")
}
}