Deprecate dns_hijack and dns inbound

This commit is contained in:
世界 2022-07-23 09:15:47 +08:00
parent 9f8978bbcf
commit 884c0cf595
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
18 changed files with 50 additions and 83 deletions

View file

@ -53,7 +53,7 @@ func DomainNameQuery(ctx context.Context, packet []byte) (*adapter.InboundContex
}
domain := question.Name.String()
if question.Class == dnsmessage.ClassINET && (question.Type == dnsmessage.TypeA || question.Type == dnsmessage.TypeAAAA) && IsDomainName(domain) {
return &adapter.InboundContext{Protocol: C.ProtocolDNS, Domain: domain}, nil
return &adapter.InboundContext{Protocol: C.ProtocolDNS /*, Domain: domain*/}, nil
}
return nil, os.ErrInvalid
}

View file

@ -4,9 +4,9 @@ const (
TypeTun = "tun"
TypeRedirect = "redirect"
TypeTProxy = "tproxy"
TypeDNS = "dns"
TypeDirect = "direct"
TypeBlock = "block"
TypeDNS = "dns"
TypeSocks = "socks"
TypeHTTP = "http"
TypeMixed = "mixed"

View file

@ -22,8 +22,6 @@ func New(ctx context.Context, router adapter.Router, logger log.ContextLogger, o
return NewRedirect(ctx, router, logger, options.Tag, options.RedirectOptions), nil
case C.TypeTProxy:
return NewTProxy(ctx, router, logger, options.Tag, options.TProxyOptions), nil
case C.TypeDNS:
return NewDNS(ctx, router, logger, options.Tag, options.DNSOptions), nil
case C.TypeDirect:
return NewDirect(ctx, router, logger, options.Tag, options.DirectOptions), nil
case C.TypeSocks:

View file

@ -21,7 +21,6 @@ import (
F "github.com/sagernet/sing/common/format"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
"github.com/sagernet/sing/common/task"
)
var _ adapter.Inbound = (*Tun)(nil)
@ -38,7 +37,6 @@ type Tun struct {
inet4Address netip.Prefix
inet6Address netip.Prefix
autoRoute bool
hijackDNS bool
tunIf tun.Tun
tunStack *tun.GVisorTun
@ -64,7 +62,6 @@ func NewTun(ctx context.Context, router adapter.Router, logger log.ContextLogger
inet4Address: options.Inet4Address.Build(),
inet6Address: options.Inet6Address.Build(),
autoRoute: options.AutoRoute,
hijackDNS: options.HijackDNS,
}, nil
}
@ -109,11 +106,6 @@ func (t *Tun) NewConnection(ctx context.Context, conn net.Conn, upstreamMetadata
metadata.SniffEnabled = t.inboundOptions.SniffEnabled
metadata.SniffOverrideDestination = t.inboundOptions.SniffOverrideDestination
metadata.DomainStrategy = dns.DomainStrategy(t.inboundOptions.DomainStrategy)
if t.hijackDNS && upstreamMetadata.Destination.Port == 53 {
return task.Run(ctx, func() error {
return NewDNSConnection(ctx, t.router, t.logger, conn, metadata)
})
}
t.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
t.logger.InfoContext(ctx, "inbound connection to ", metadata.Destination)
err := t.router.RouteConnection(ctx, conn, metadata)
@ -134,11 +126,6 @@ func (t *Tun) NewPacketConnection(ctx context.Context, conn N.PacketConn, upstre
metadata.SniffEnabled = t.inboundOptions.SniffEnabled
metadata.SniffOverrideDestination = t.inboundOptions.SniffOverrideDestination
metadata.DomainStrategy = dns.DomainStrategy(t.inboundOptions.DomainStrategy)
if t.hijackDNS && upstreamMetadata.Destination.Port == 53 {
return task.Run(ctx, func() error {
return NewDNSPacketConnection(ctx, t.router, t.logger, conn, metadata)
})
}
t.logger.InfoContext(ctx, "inbound packet connection from ", metadata.Source)
t.logger.InfoContext(ctx, "inbound packet connection to ", metadata.Destination)
err := t.router.RoutePacketConnection(ctx, conn, metadata)

View file

@ -15,7 +15,6 @@ type _Inbound struct {
TunOptions TunInboundOptions `json:"-"`
RedirectOptions RedirectInboundOptions `json:"-"`
TProxyOptions TProxyInboundOptions `json:"-"`
DNSOptions DNSInboundOptions `json:"-"`
DirectOptions DirectInboundOptions `json:"-"`
SocksOptions SocksInboundOptions `json:"-"`
HTTPOptions HTTPMixedInboundOptions `json:"-"`
@ -32,7 +31,6 @@ func (h Inbound) Equals(other Inbound) bool {
h.TunOptions == other.TunOptions &&
h.RedirectOptions == other.RedirectOptions &&
h.TProxyOptions == other.TProxyOptions &&
h.DNSOptions == other.DNSOptions &&
h.DirectOptions == other.DirectOptions &&
h.SocksOptions.Equals(other.SocksOptions) &&
h.HTTPOptions.Equals(other.HTTPOptions) &&
@ -50,8 +48,6 @@ func (h Inbound) MarshalJSON() ([]byte, error) {
v = h.RedirectOptions
case C.TypeTProxy:
v = h.TProxyOptions
case C.TypeDNS:
v = h.DNSOptions
case C.TypeDirect:
v = h.DirectOptions
case C.TypeSocks:
@ -83,8 +79,6 @@ func (h *Inbound) UnmarshalJSON(bytes []byte) error {
v = &h.RedirectOptions
case C.TypeTProxy:
v = &h.TProxyOptions
case C.TypeDNS:
v = &h.DNSOptions
case C.TypeDirect:
v = &h.DirectOptions
case C.TypeSocks:
@ -200,7 +194,6 @@ type TunInboundOptions struct {
Inet4Address *ListenPrefix `json:"inet4_address,omitempty"`
Inet6Address *ListenPrefix `json:"inet6_address,omitempty"`
AutoRoute bool `json:"auto_route,omitempty"`
HijackDNS bool `json:"hijack_dns,omitempty"`
InboundOptions
}

View file

@ -40,7 +40,7 @@ func (h Outbound) MarshalJSON() ([]byte, error) {
switch h.Type {
case C.TypeDirect:
v = h.DirectOptions
case C.TypeBlock:
case C.TypeBlock, C.TypeDNS:
v = nil
case C.TypeSocks:
v = h.SocksOptions
@ -69,7 +69,7 @@ func (h *Outbound) UnmarshalJSON(bytes []byte) error {
switch h.Type {
case C.TypeDirect:
v = &h.DirectOptions
case C.TypeBlock:
case C.TypeBlock, C.TypeDNS:
v = nil
case C.TypeSocks:
v = &h.SocksOptions

View file

@ -22,9 +22,9 @@ func NewBlock(logger log.ContextLogger, tag string) *Block {
return &Block{
myOutboundAdapter{
protocol: C.TypeBlock,
network: []string{C.NetworkTCP, C.NetworkUDP},
logger: logger,
tag: tag,
network: []string{C.NetworkTCP, C.NetworkUDP},
},
}
}

View file

@ -18,6 +18,8 @@ func New(router adapter.Router, logger log.ContextLogger, options option.Outboun
return NewDirect(router, logger, options.Tag, options.DirectOptions), nil
case C.TypeBlock:
return NewBlock(logger, options.Tag), nil
case C.TypeDNS:
return NewDNS(router, logger, options.Tag), nil
case C.TypeSocks:
return NewSocks(router, logger, options.Tag, options.SocksOptions)
case C.TypeHTTP:

View file

@ -18,9 +18,10 @@ import (
type myOutboundAdapter struct {
protocol string
network []string
router adapter.Router
logger log.ContextLogger
tag string
network []string
}
func (a *myOutboundAdapter) Type() string {

View file

@ -27,9 +27,10 @@ func NewDirect(router adapter.Router, logger log.ContextLogger, tag string, opti
outbound := &Direct{
myOutboundAdapter: myOutboundAdapter{
protocol: C.TypeDirect,
network: []string{C.NetworkTCP, C.NetworkUDP},
router: router,
logger: logger,
tag: tag,
network: []string{C.NetworkTCP, C.NetworkUDP},
},
dialer: dialer.NewOutbound(router, options.OutboundDialerOptions),
}

View file

@ -1,67 +1,50 @@
package inbound
package outbound
import (
"context"
"encoding/binary"
"io"
"net"
"net/netip"
"os"
"github.com/sagernet/sing-box/adapter"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
"github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/buf"
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
"github.com/sagernet/sing/common/udpnat"
"golang.org/x/net/dns/dnsmessage"
)
var _ adapter.Outbound = (*DNS)(nil)
type DNS struct {
myInboundAdapter
udpNat *udpnat.Service[netip.AddrPort]
myOutboundAdapter
}
func NewDNS(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.DNSInboundOptions) *DNS {
dns := &DNS{
myInboundAdapter: myInboundAdapter{
protocol: C.TypeTProxy,
network: options.Network.Build(),
ctx: ctx,
router: router,
logger: logger,
tag: tag,
listenOptions: options.ListenOptions,
func NewDNS(router adapter.Router, logger log.ContextLogger, tag string) *DNS {
return &DNS{
myOutboundAdapter{
protocol: C.TypeDNS,
network: []string{C.NetworkTCP, C.NetworkUDP},
router: router,
logger: logger,
tag: tag,
},
}
dns.connHandler = dns
dns.packetHandler = dns
dns.udpNat = udpnat.New[netip.AddrPort](10, adapter.NewUpstreamContextHandler(nil, dns.newPacketConnection, dns))
dns.packetUpstream = dns.udpNat
return dns
}
func (d *DNS) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
return nil, os.ErrInvalid
}
func (d *DNS) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
return nil, os.ErrInvalid
}
func (d *DNS) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
return NewDNSConnection(ctx, d.router, d.logger, conn, metadata)
}
func (d *DNS) NewPacket(ctx context.Context, conn N.PacketConn, buffer *buf.Buffer, metadata adapter.InboundContext) error {
d.udpNat.NewContextPacket(ctx, metadata.Source.AddrPort(), buffer, adapter.UpstreamMetadata(metadata), func(natConn N.PacketConn) (context.Context, N.PacketWriter) {
return adapter.WithContext(log.ContextWithNewID(ctx), &metadata), &udpnat.DirectBackWriter{
Source: conn,
Nat: natConn,
}
})
return nil
}
func (d *DNS) newPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
return NewDNSPacketConnection(ctx, d.router, d.logger, conn, metadata)
}
func NewDNSConnection(ctx context.Context, router adapter.Router, logger log.ContextLogger, conn net.Conn, metadata adapter.InboundContext) error {
ctx = adapter.WithContext(ctx, &metadata)
_buffer := buf.StackNewSize(1024)
defer common.KeepAlive(_buffer)
@ -89,10 +72,10 @@ func NewDNSConnection(ctx context.Context, router adapter.Router, logger log.Con
if len(message.Questions) > 0 {
question := message.Questions[0]
metadata.Domain = string(question.Name.Data[:question.Name.Length-1])
logger.DebugContext(ctx, "inbound dns query ", formatDNSQuestion(question), " from ", metadata.Source)
d.logger.DebugContext(ctx, "inbound dns query ", formatDNSQuestion(question), " from ", metadata.Source)
}
go func() error {
response, err := router.Exchange(ctx, &message)
response, err := d.router.Exchange(ctx, &message)
if err != nil {
return err
}
@ -113,7 +96,7 @@ func NewDNSConnection(ctx context.Context, router adapter.Router, logger log.Con
}
}
func NewDNSPacketConnection(ctx context.Context, router adapter.Router, logger log.ContextLogger, conn N.PacketConn, metadata adapter.InboundContext) error {
func (d *DNS) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
ctx = adapter.WithContext(ctx, &metadata)
_buffer := buf.StackNewSize(1024)
defer common.KeepAlive(_buffer)
@ -133,10 +116,10 @@ func NewDNSPacketConnection(ctx context.Context, router adapter.Router, logger l
if len(message.Questions) > 0 {
question := message.Questions[0]
metadata.Domain = string(question.Name.Data[:question.Name.Length-1])
logger.DebugContext(ctx, "inbound dns query ", formatDNSQuestion(question), " from ", metadata.Source)
d.logger.DebugContext(ctx, "inbound dns query ", formatDNSQuestion(question), " from ", metadata.Source)
}
go func() error {
response, err := router.Exchange(ctx, &message)
response, err := d.router.Exchange(ctx, &message)
if err != nil {
return err
}

View file

@ -31,9 +31,10 @@ func NewHTTP(router adapter.Router, logger log.ContextLogger, tag string, option
return &HTTP{
myOutboundAdapter{
protocol: C.TypeHTTP,
network: []string{C.NetworkTCP},
router: router,
logger: logger,
tag: tag,
network: []string{C.NetworkTCP},
},
http.NewClient(detour, options.ServerOptions.Build(), options.Username, options.Password),
}, nil

View file

@ -20,7 +20,6 @@ var (
type Selector struct {
myOutboundAdapter
router adapter.Router
tags []string
defaultTag string
outbounds map[string]adapter.Outbound
@ -31,10 +30,10 @@ func NewSelector(router adapter.Router, logger log.ContextLogger, tag string, op
outbound := &Selector{
myOutboundAdapter: myOutboundAdapter{
protocol: C.TypeSelector,
router: router,
logger: logger,
tag: tag,
},
router: router,
tags: options.Outbounds,
defaultTag: options.Default,
outbounds: make(map[string]adapter.Outbound),

View file

@ -33,9 +33,10 @@ func NewShadowsocks(router adapter.Router, logger log.ContextLogger, tag string,
return &Shadowsocks{
myOutboundAdapter{
protocol: C.TypeShadowsocks,
network: options.Network.Build(),
router: router,
logger: logger,
tag: tag,
network: options.Network.Build(),
},
dialer.NewOutbound(router, options.OutboundDialerOptions),
method,

View file

@ -36,9 +36,10 @@ func NewSocks(router adapter.Router, logger log.ContextLogger, tag string, optio
return &Socks{
myOutboundAdapter{
protocol: C.TypeSocks,
network: options.Network.Build(),
router: router,
logger: logger,
tag: tag,
network: options.Network.Build(),
},
socks.NewClient(detour, options.ServerOptions.Build(), version, options.Username, options.Password),
}, nil

View file

@ -24,7 +24,6 @@ var (
type URLTest struct {
myOutboundAdapter
router adapter.Router
tags []string
link string
interval time.Duration
@ -36,10 +35,10 @@ func NewURLTest(router adapter.Router, logger log.ContextLogger, tag string, opt
outbound := &URLTest{
myOutboundAdapter: myOutboundAdapter{
protocol: C.TypeURLTest,
router: router,
logger: logger,
tag: tag,
},
router: router,
tags: options.Outbounds,
link: options.URL,
interval: time.Duration(options.Interval),

View file

@ -43,9 +43,10 @@ func NewVMess(router adapter.Router, logger log.ContextLogger, tag string, optio
return &VMess{
myOutboundAdapter{
protocol: C.TypeVMess,
network: options.Network.Build(),
router: router,
logger: logger,
tag: tag,
network: options.Network.Build(),
},
detour,
client,

View file

@ -439,7 +439,7 @@ func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, metadata ad
defer common.KeepAlive(_buffer)
buffer := common.Dup(_buffer)
defer buffer.Release()
sniffMetadata, err := sniff.PeekStream(ctx, conn, buffer, sniff.TLSClientHello, sniff.HTTPHost)
sniffMetadata, err := sniff.PeekStream(ctx, conn, buffer, sniff.StreamDomainNameQuery, sniff.TLSClientHello, sniff.HTTPHost)
if err == nil {
metadata.Protocol = sniffMetadata.Protocol
metadata.Domain = sniffMetadata.Domain
@ -485,7 +485,7 @@ func (r *Router) RoutePacketConnection(ctx context.Context, conn N.PacketConn, m
if err != nil {
return err
}
sniffMetadata, err := sniff.PeekPacket(ctx, buffer.Bytes(), sniff.QUICClientHello, sniff.STUNMessage)
sniffMetadata, err := sniff.PeekPacket(ctx, buffer.Bytes(), sniff.DomainNameQuery, sniff.QUICClientHello, sniff.STUNMessage)
originDestination := metadata.Destination
if err == nil {
metadata.Protocol = sniffMetadata.Protocol