Files
sing-box-extended-mirror/route/dns.go
T

110 lines
3.3 KiB
Go
Raw Normal View History

2024-10-23 13:44:08 +08:00
package route
import (
"context"
"net"
"time"
"github.com/sagernet/sing-box/adapter"
C "github.com/sagernet/sing-box/constant"
2025-03-16 14:50:44 +08:00
"github.com/sagernet/sing-box/dns"
2024-11-02 00:39:02 +08:00
dnsOutbound "github.com/sagernet/sing-box/protocol/dns"
2025-06-20 13:12:49 +08:00
R "github.com/sagernet/sing-box/route/rule"
2024-10-23 13:44:08 +08:00
"github.com/sagernet/sing/common/buf"
E "github.com/sagernet/sing/common/exceptions"
2025-03-16 14:50:44 +08:00
"github.com/sagernet/sing/common/logger"
2024-10-23 13:44:08 +08:00
M "github.com/sagernet/sing/common/metadata"
N "github.com/sagernet/sing/common/network"
"github.com/sagernet/sing/common/udpnat2"
mDNS "github.com/miekg/dns"
)
func (r *Router) hijackDNSStream(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
metadata.Destination = M.Socksaddr{}
for {
conn.SetReadDeadline(time.Now().Add(C.DNSTimeout))
2025-03-16 14:50:44 +08:00
err := dnsOutbound.HandleStreamDNSRequest(ctx, r.dns, conn, metadata)
2024-10-23 13:44:08 +08:00
if err != nil {
2025-03-30 23:34:15 +08:00
if !E.IsClosedOrCanceled(err) {
return err
} else {
return nil
}
2024-10-23 13:44:08 +08:00
}
}
}
2025-03-30 23:34:15 +08:00
func (r *Router) hijackDNSPacket(ctx context.Context, conn N.PacketConn, packetBuffers []*N.PacketBuffer, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) error {
2024-11-20 11:32:02 +08:00
if natConn, isNatConn := conn.(udpnat.Conn); isNatConn {
2024-10-23 13:44:08 +08:00
metadata.Destination = M.Socksaddr{}
for _, packet := range packetBuffers {
buffer := packet.Buffer
destination := packet.Destination
N.PutPacketBuffer(packet)
2025-03-16 14:50:44 +08:00
go ExchangeDNSPacket(ctx, r.dns, r.logger, natConn, buffer, metadata, destination)
2024-10-23 13:44:08 +08:00
}
2024-11-20 11:32:02 +08:00
natConn.SetHandler(&dnsHijacker{
2025-03-16 14:50:44 +08:00
router: r.dns,
logger: r.logger,
2024-10-23 13:44:08 +08:00
conn: conn,
ctx: ctx,
metadata: metadata,
2025-06-06 14:28:09 +08:00
onClose: onClose,
2024-10-23 13:44:08 +08:00
})
2025-03-30 23:34:15 +08:00
return nil
2024-10-23 13:44:08 +08:00
}
2025-03-16 14:50:44 +08:00
err := dnsOutbound.NewDNSPacketConnection(ctx, r.dns, conn, packetBuffers, metadata)
2025-06-06 14:28:09 +08:00
N.CloseOnHandshakeFailure(conn, onClose, err)
2024-10-23 13:44:08 +08:00
if err != nil && !E.IsClosedOrCanceled(err) {
2025-03-30 23:34:15 +08:00
return E.Cause(err, "process DNS packet")
2024-10-23 13:44:08 +08:00
}
2025-03-30 23:34:15 +08:00
return nil
2024-10-23 13:44:08 +08:00
}
2025-03-16 14:50:44 +08:00
func ExchangeDNSPacket(ctx context.Context, router adapter.DNSRouter, logger logger.ContextLogger, conn N.PacketConn, buffer *buf.Buffer, metadata adapter.InboundContext, destination M.Socksaddr) {
2024-10-23 13:44:08 +08:00
err := exchangeDNSPacket(ctx, router, conn, buffer, metadata, destination)
2025-06-20 13:12:49 +08:00
if err != nil && !R.IsRejected(err) && !E.IsClosedOrCanceled(err) {
2025-03-30 23:34:15 +08:00
logger.ErrorContext(ctx, E.Cause(err, "process DNS packet"))
2024-10-23 13:44:08 +08:00
}
}
2025-03-16 14:50:44 +08:00
func exchangeDNSPacket(ctx context.Context, router adapter.DNSRouter, conn N.PacketConn, buffer *buf.Buffer, metadata adapter.InboundContext, destination M.Socksaddr) error {
2024-10-23 13:44:08 +08:00
var message mDNS.Msg
err := message.Unpack(buffer.Bytes())
buffer.Release()
if err != nil {
return E.Cause(err, "unpack request")
}
2025-03-16 14:50:44 +08:00
response, err := router.Exchange(adapter.WithContext(ctx, &metadata), &message, adapter.DNSQueryOptions{})
2024-10-23 13:44:08 +08:00
if err != nil {
return err
}
responseBuffer, err := dns.TruncateDNSMessage(&message, response, 1024)
if err != nil {
return err
}
err = conn.WritePacket(responseBuffer, destination)
return err
}
type dnsHijacker struct {
2025-03-16 14:50:44 +08:00
router adapter.DNSRouter
logger logger.ContextLogger
2024-10-23 13:44:08 +08:00
conn N.PacketConn
ctx context.Context
metadata adapter.InboundContext
2025-06-06 14:28:09 +08:00
onClose N.CloseHandlerFunc
2024-10-23 13:44:08 +08:00
}
func (h *dnsHijacker) NewPacketEx(buffer *buf.Buffer, destination M.Socksaddr) {
2025-03-16 14:50:44 +08:00
go ExchangeDNSPacket(h.ctx, h.router, h.logger, h.conn, buffer, h.metadata, destination)
2024-10-23 13:44:08 +08:00
}
2025-06-06 14:28:09 +08:00
func (h *dnsHijacker) Close() error {
if h.onClose != nil {
h.onClose(nil)
}
return nil
}