Fix ping domain
This commit is contained in:
@@ -17,6 +17,7 @@ import (
|
|||||||
R "github.com/sagernet/sing-box/route/rule"
|
R "github.com/sagernet/sing-box/route/rule"
|
||||||
"github.com/sagernet/sing-mux"
|
"github.com/sagernet/sing-mux"
|
||||||
"github.com/sagernet/sing-tun"
|
"github.com/sagernet/sing-tun"
|
||||||
|
"github.com/sagernet/sing-tun/ping"
|
||||||
"github.com/sagernet/sing-vmess"
|
"github.com/sagernet/sing-vmess"
|
||||||
"github.com/sagernet/sing/common"
|
"github.com/sagernet/sing/common"
|
||||||
"github.com/sagernet/sing/common/buf"
|
"github.com/sagernet/sing/common/buf"
|
||||||
@@ -271,6 +272,7 @@ func (r *Router) PreMatch(metadata adapter.InboundContext, routeContext tun.Dire
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
var directRouteOutbound adapter.DirectRouteOutbound
|
||||||
if selectedRule != nil {
|
if selectedRule != nil {
|
||||||
switch action := selectedRule.Action().(type) {
|
switch action := selectedRule.Action().(type) {
|
||||||
case *R.RuleActionReject:
|
case *R.RuleActionReject:
|
||||||
@@ -296,17 +298,69 @@ func (r *Router) PreMatch(metadata adapter.InboundContext, routeContext tun.Dire
|
|||||||
if !common.Contains(outbound.Network(), metadata.Network) {
|
if !common.Contains(outbound.Network(), metadata.Network) {
|
||||||
return nil, E.New(metadata.Network, " is not supported by outbound: ", action.Outbound)
|
return nil, E.New(metadata.Network, " is not supported by outbound: ", action.Outbound)
|
||||||
}
|
}
|
||||||
return outbound.(adapter.DirectRouteOutbound).NewDirectRouteConnection(metadata, routeContext, timeout)
|
directRouteOutbound = outbound.(adapter.DirectRouteOutbound)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if selectedRule != nil || metadata.Network != N.NetworkICMP {
|
if directRouteOutbound == nil {
|
||||||
return nil, nil
|
if selectedRule != nil || metadata.Network != N.NetworkICMP {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
defaultOutbound := r.outbound.Default()
|
||||||
|
if !common.Contains(defaultOutbound.Network(), metadata.Network) {
|
||||||
|
return nil, E.New(metadata.Network, " is not supported by default outbound: ", defaultOutbound.Tag())
|
||||||
|
}
|
||||||
|
directRouteOutbound = defaultOutbound.(adapter.DirectRouteOutbound)
|
||||||
}
|
}
|
||||||
defaultOutbound := r.outbound.Default()
|
if metadata.Destination.IsFqdn() {
|
||||||
if !common.Contains(defaultOutbound.Network(), metadata.Network) {
|
if len(metadata.DestinationAddresses) == 0 {
|
||||||
return nil, E.New(metadata.Network, " is not supported by default outbound: ", defaultOutbound.Tag())
|
var strategy C.DomainStrategy
|
||||||
|
if metadata.Source.IsIPv4() {
|
||||||
|
strategy = C.DomainStrategyIPv4Only
|
||||||
|
} else {
|
||||||
|
strategy = C.DomainStrategyIPv6Only
|
||||||
|
}
|
||||||
|
err = r.actionResolve(r.ctx, &metadata, &R.RuleActionResolve{
|
||||||
|
Strategy: strategy,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var newDestination netip.Addr
|
||||||
|
if metadata.Source.IsIPv4() {
|
||||||
|
for _, address := range metadata.DestinationAddresses {
|
||||||
|
if address.Is4() {
|
||||||
|
newDestination = address
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for _, address := range metadata.DestinationAddresses {
|
||||||
|
if address.Is6() {
|
||||||
|
newDestination = address
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !newDestination.IsValid() {
|
||||||
|
if metadata.Source.IsIPv4() {
|
||||||
|
return nil, E.New("no IPv4 address found for domain: ", metadata.Destination.Fqdn)
|
||||||
|
} else {
|
||||||
|
return nil, E.New("no IPv6 address found for domain: ", metadata.Destination.Fqdn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
metadata.Destination = M.Socksaddr{
|
||||||
|
Addr: newDestination,
|
||||||
|
}
|
||||||
|
routeContext = ping.NewContextDestinationWriter(routeContext, metadata.OriginDestination.Addr)
|
||||||
|
var routeDestination tun.DirectRouteDestination
|
||||||
|
routeDestination, err = directRouteOutbound.NewDirectRouteConnection(metadata, routeContext, timeout)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return ping.NewDestinationWriter(routeDestination, newDestination), nil
|
||||||
}
|
}
|
||||||
return defaultOutbound.(adapter.DirectRouteOutbound).NewDirectRouteConnection(metadata, routeContext, timeout)
|
return directRouteOutbound.NewDirectRouteConnection(metadata, routeContext, timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Router) matchRule(
|
func (r *Router) matchRule(
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ type natDeviceWrapper struct {
|
|||||||
ctx context.Context
|
ctx context.Context
|
||||||
logger logger.ContextLogger
|
logger logger.ContextLogger
|
||||||
packetOutbound chan *buf.Buffer
|
packetOutbound chan *buf.Buffer
|
||||||
rewriter *ping.Rewriter
|
rewriter *ping.SourceRewriter
|
||||||
buffer [][]byte
|
buffer [][]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ func NewNATDevice(ctx context.Context, logger logger.ContextLogger, upstream Dev
|
|||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
packetOutbound: make(chan *buf.Buffer, 256),
|
packetOutbound: make(chan *buf.Buffer, 256),
|
||||||
rewriter: ping.NewRewriter(ctx, logger, upstream.Inet4Address(), upstream.Inet6Address()),
|
rewriter: ping.NewSourceRewriter(ctx, logger, upstream.Inet4Address(), upstream.Inet6Address()),
|
||||||
}
|
}
|
||||||
return wrapper
|
return wrapper
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user