mirror of
https://github.com/SagerNet/sing-box.git
synced 2024-11-25 10:01:30 +00:00
Refactor to miekg/dns
This commit is contained in:
parent
1db7f45370
commit
007a278ac8
|
@ -11,7 +11,7 @@ import (
|
|||
"github.com/sagernet/sing/common/control"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
|
||||
"golang.org/x/net/dns/dnsmessage"
|
||||
mdns "github.com/miekg/dns"
|
||||
)
|
||||
|
||||
type Router interface {
|
||||
|
@ -27,7 +27,7 @@ type Router interface {
|
|||
GeoIPReader() *geoip.Reader
|
||||
LoadGeosite(code string) (Rule, error)
|
||||
|
||||
Exchange(ctx context.Context, message *dnsmessage.Message) (*dnsmessage.Message, error)
|
||||
Exchange(ctx context.Context, message *mdns.Msg) (*mdns.Msg, error)
|
||||
Lookup(ctx context.Context, domain string, strategy dns.DomainStrategy) ([]netip.Addr, error)
|
||||
LookupDefault(ctx context.Context, domain string) ([]netip.Addr, error)
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ import (
|
|||
"github.com/sagernet/sing/common/buf"
|
||||
"github.com/sagernet/sing/common/task"
|
||||
|
||||
"golang.org/x/net/dns/dnsmessage"
|
||||
mDNS "github.com/miekg/dns"
|
||||
)
|
||||
|
||||
func StreamDomainNameQuery(readCtx context.Context, reader io.Reader) (*adapter.InboundContext, error) {
|
||||
|
@ -44,18 +44,10 @@ func StreamDomainNameQuery(readCtx context.Context, reader io.Reader) (*adapter.
|
|||
}
|
||||
|
||||
func DomainNameQuery(ctx context.Context, packet []byte) (*adapter.InboundContext, error) {
|
||||
var parser dnsmessage.Parser
|
||||
_, err := parser.Start(packet)
|
||||
var msg mDNS.Msg
|
||||
err := msg.Unpack(packet)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
question, err := parser.Question()
|
||||
if err != nil {
|
||||
return nil, os.ErrInvalid
|
||||
}
|
||||
domain := question.Name.String()
|
||||
if question.Class == dnsmessage.ClassINET && IsDomainName(domain) {
|
||||
return &adapter.InboundContext{Protocol: C.ProtocolDNS /*, Domain: domain*/}, nil
|
||||
}
|
||||
return nil, os.ErrInvalid
|
||||
return &adapter.InboundContext{Protocol: C.ProtocolDNS}, nil
|
||||
}
|
||||
|
|
|
@ -7,11 +7,11 @@ import (
|
|||
"crypto/tls"
|
||||
"strings"
|
||||
|
||||
"github.com/sagernet/certmagic"
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
|
||||
"github.com/caddyserver/certmagic"
|
||||
"github.com/mholt/acmez/acme"
|
||||
)
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@ import (
|
|||
E "github.com/sagernet/sing/common/exceptions"
|
||||
|
||||
mDNS "github.com/miekg/dns"
|
||||
"golang.org/x/net/dns/dnsmessage"
|
||||
)
|
||||
|
||||
type echClientConfig struct {
|
||||
|
@ -170,15 +169,15 @@ const typeHTTPS = 65
|
|||
|
||||
func fetchECHClientConfig(router adapter.Router) func(ctx context.Context, serverName string) ([]cftls.ECHConfig, error) {
|
||||
return func(ctx context.Context, serverName string) ([]cftls.ECHConfig, error) {
|
||||
message := &dnsmessage.Message{
|
||||
Header: dnsmessage.Header{
|
||||
message := &mDNS.Msg{
|
||||
MsgHdr: mDNS.MsgHdr{
|
||||
RecursionDesired: true,
|
||||
},
|
||||
Questions: []dnsmessage.Question{
|
||||
Question: []mDNS.Question{
|
||||
{
|
||||
Name: dnsmessage.MustNewName(serverName + "."),
|
||||
Type: typeHTTPS,
|
||||
Class: dnsmessage.ClassINET,
|
||||
Name: serverName + ".",
|
||||
Qtype: mDNS.TypeHTTPS,
|
||||
Qclass: mDNS.ClassINET,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -186,19 +185,10 @@ func fetchECHClientConfig(router adapter.Router) func(ctx context.Context, serve
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if response.RCode != dnsmessage.RCodeSuccess {
|
||||
return nil, dns.RCodeError(response.RCode)
|
||||
if response.Rcode != mDNS.RcodeSuccess {
|
||||
return nil, dns.RCodeError(response.Rcode)
|
||||
}
|
||||
content, err := response.Pack()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var mMsg mDNS.Msg
|
||||
err = mMsg.Unpack(content)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, rr := range mMsg.Answer {
|
||||
for _, rr := range response.Answer {
|
||||
switch resource := rr.(type) {
|
||||
case *mDNS.HTTPS:
|
||||
for _, value := range resource.Value {
|
||||
|
|
|
@ -53,17 +53,6 @@ we need to do this.
|
|||
|
||||
The library needs to be updated with the upstream.
|
||||
|
||||
#### certmagic
|
||||
|
||||
Link: [GitHub repository](https://github.com/SagerNet/certmagic)
|
||||
|
||||
Fork of `caddyserver/certmagic`
|
||||
|
||||
Since upstream uses `miekg/dns` and we use `x/net/dnsmessage`, we need to replace its DNS part with our own
|
||||
implementation.
|
||||
|
||||
The library needs to be updated with the upstream.
|
||||
|
||||
#### smux
|
||||
|
||||
Link: [GitHub repository](https://github.com/SagerNet/smux)
|
||||
|
|
4
go.mod
4
go.mod
|
@ -4,6 +4,7 @@ go 1.18
|
|||
|
||||
require (
|
||||
berty.tech/go-libtor v1.0.385
|
||||
github.com/caddyserver/certmagic v0.17.1
|
||||
github.com/cloudflare/circl v1.2.1-0.20220831060716-4cf0150356fc
|
||||
github.com/cretz/bine v0.2.0
|
||||
github.com/database64128/tfo-go v1.1.2
|
||||
|
@ -20,11 +21,10 @@ require (
|
|||
github.com/oschwald/maxminddb-golang v1.10.0
|
||||
github.com/pires/go-proxyproto v0.6.2
|
||||
github.com/refraction-networking/utls v1.1.2
|
||||
github.com/sagernet/certmagic v0.0.0-20220819042630-4a57f8b6853a
|
||||
github.com/sagernet/quic-go v0.0.0-20220818150011-de611ab3e2bb
|
||||
github.com/sagernet/shadowsocksr v0.0.0-20220912092645-c9ab93f81bb0
|
||||
github.com/sagernet/sing v0.0.0-20220913004915-27ddefbb8921
|
||||
github.com/sagernet/sing-dns v0.0.0-20220822023312-3e086b06d666
|
||||
github.com/sagernet/sing-dns v0.0.0-20220913080251-628caf4acef7
|
||||
github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6
|
||||
github.com/sagernet/sing-tun v0.0.0-20220911034209-c7dd5d457e24
|
||||
github.com/sagernet/sing-vmess v0.0.0-20220913015714-c4ab86d40e12
|
||||
|
|
8
go.sum
8
go.sum
|
@ -10,6 +10,8 @@ github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHG
|
|||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/caddyserver/certmagic v0.17.1 h1:VrWANhQAj3brK7jAUKyN6XBHg56WsyorI/84Ilq1tCQ=
|
||||
github.com/caddyserver/certmagic v0.17.1/go.mod h1:pSS2aZcdKlrTZrb2DKuRafckx20o5Fz1EdDKEB8KOQM=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/circl v1.2.1-0.20220831060716-4cf0150356fc h1:307gdRLiZ08dwOIKwc5lAQ19DRFaQQvdhHalyB4Asx8=
|
||||
|
@ -133,8 +135,6 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L
|
|||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sagernet/abx-go v0.0.0-20220819185957-dba1257d738e h1:5CFRo8FJbCuf5s/eTBdZpmMbn8Fe2eSMLNAYfKanA34=
|
||||
github.com/sagernet/abx-go v0.0.0-20220819185957-dba1257d738e/go.mod h1:qbt0dWObotCfcjAJJ9AxtFPNSDUfZF+6dCpgKEOBn/g=
|
||||
github.com/sagernet/certmagic v0.0.0-20220819042630-4a57f8b6853a h1:SE3Xn4GOQ+kxbgGa2Xp0H2CCsx1o2pVTt0f+hmfuHH4=
|
||||
github.com/sagernet/certmagic v0.0.0-20220819042630-4a57f8b6853a/go.mod h1:Q+ZXyesnkjV5B70B1ixk65ecKrlJ2jz0atv3fPKsVVo=
|
||||
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 h1:5+m7c6AkmAylhauulqN/c5dnh8/KssrE9c93TQrXldA=
|
||||
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61/go.mod h1:QUQ4RRHD6hGGHdFMEtR8T2P6GS6R3D/CXKdaYHKKXms=
|
||||
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 h1:iL5gZI3uFp0X6EslacyapiRz7LLSJyr4RajF/BhMVyE=
|
||||
|
@ -147,8 +147,8 @@ github.com/sagernet/sing v0.0.0-20220812082120-05f9836bff8f/go.mod h1:QVsS5L/ZA2
|
|||
github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
|
||||
github.com/sagernet/sing v0.0.0-20220913004915-27ddefbb8921 h1:xUHzlIbdlPV/fkToIO9futp9lmKIY+72ezk/whQ8XsI=
|
||||
github.com/sagernet/sing v0.0.0-20220913004915-27ddefbb8921/go.mod h1:kZvzh1VDa/Dg/Bt5WaYKU0jl5ept8KKDpl3Ay4gRtRQ=
|
||||
github.com/sagernet/sing-dns v0.0.0-20220822023312-3e086b06d666 h1:XUTocA/Ek0dFxUX+xJCWMPPFZCn2GC/uLrBjTSr1vHY=
|
||||
github.com/sagernet/sing-dns v0.0.0-20220822023312-3e086b06d666/go.mod h1:eDyH7AJmqBGjZQdQmpZIzlbTREudZuWDExMuGKgjRVM=
|
||||
github.com/sagernet/sing-dns v0.0.0-20220913080251-628caf4acef7 h1:hGmqtoGifhIy/XFczifR4coknjBIE8f1Suyd1SJc2F4=
|
||||
github.com/sagernet/sing-dns v0.0.0-20220913080251-628caf4acef7/go.mod h1:NxH8BRDCYo28ZoojuNdRZEt9zbYgyAvC7WxEEkaUBCM=
|
||||
github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6 h1:JJfDeYYhWunvtxsU/mOVNTmFQmnzGx9dY034qG6G3g4=
|
||||
github.com/sagernet/sing-shadowsocks v0.0.0-20220819002358-7461bb09a8f6/go.mod h1:EX3RbZvrwAkPI2nuGa78T2iQXmrkT+/VQtskjou42xM=
|
||||
github.com/sagernet/sing-tun v0.0.0-20220911034209-c7dd5d457e24 h1:LsmPeFvj4GhiV5Y7Rm8I845XysdxVN4MQmfZ36P5bmw=
|
||||
|
|
|
@ -16,7 +16,7 @@ import (
|
|||
N "github.com/sagernet/sing/common/network"
|
||||
"github.com/sagernet/sing/common/task"
|
||||
|
||||
"golang.org/x/net/dns/dnsmessage"
|
||||
mDNS "github.com/miekg/dns"
|
||||
)
|
||||
|
||||
var _ adapter.Outbound = (*DNS)(nil)
|
||||
|
@ -72,7 +72,7 @@ func (d *DNS) handleConnection(ctx context.Context, conn net.Conn, metadata adap
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var message dnsmessage.Message
|
||||
var message mDNS.Msg
|
||||
err = message.Unpack(buffer.Bytes())
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -88,7 +88,7 @@ func (d *DNS) handleConnection(ctx context.Context, conn net.Conn, metadata adap
|
|||
responseBuffer := common.Dup(_responseBuffer)
|
||||
defer responseBuffer.Release()
|
||||
responseBuffer.Resize(2, 0)
|
||||
n, err := response.AppendPack(responseBuffer.Index(0))
|
||||
n, err := response.PackBuffer(responseBuffer.FreeBytes())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ func (d *DNS) NewPacketConnection(ctx context.Context, conn N.PacketConn, metada
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var message dnsmessage.Message
|
||||
var message mDNS.Msg
|
||||
err = message.Unpack(buffer.Bytes())
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -131,7 +131,7 @@ func (d *DNS) NewPacketConnection(ctx context.Context, conn N.PacketConn, metada
|
|||
}
|
||||
timeout.Update()
|
||||
responseBuffer := buf.NewPacket()
|
||||
n, err := response.AppendPack(responseBuffer.Index(0))
|
||||
n, err := response.PackBuffer(responseBuffer.FreeBytes())
|
||||
if err != nil {
|
||||
responseBuffer.Release()
|
||||
return err
|
||||
|
|
|
@ -12,7 +12,7 @@ import (
|
|||
E "github.com/sagernet/sing/common/exceptions"
|
||||
F "github.com/sagernet/sing/common/format"
|
||||
|
||||
"golang.org/x/net/dns/dnsmessage"
|
||||
mDNS "github.com/miekg/dns"
|
||||
)
|
||||
|
||||
func (r *Router) matchDNS(ctx context.Context) (context.Context, dns.Transport, dns.DomainStrategy) {
|
||||
|
@ -40,29 +40,29 @@ func (r *Router) matchDNS(ctx context.Context) (context.Context, dns.Transport,
|
|||
return ctx, r.defaultTransport, r.defaultDomainStrategy
|
||||
}
|
||||
|
||||
func (r *Router) Exchange(ctx context.Context, message *dnsmessage.Message) (*dnsmessage.Message, error) {
|
||||
if len(message.Questions) > 0 {
|
||||
r.dnsLogger.DebugContext(ctx, "exchange ", formatDNSQuestion(message.Questions[0]))
|
||||
func (r *Router) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
|
||||
if len(message.Question) > 0 {
|
||||
r.dnsLogger.DebugContext(ctx, "exchange ", formatQuestion(message.Question[0].String()))
|
||||
}
|
||||
ctx, metadata := adapter.AppendContext(ctx)
|
||||
if len(message.Questions) > 0 {
|
||||
switch message.Questions[0].Type {
|
||||
case dnsmessage.TypeA:
|
||||
if len(message.Question) > 0 {
|
||||
switch message.Question[0].Qtype {
|
||||
case mDNS.TypeA:
|
||||
metadata.IPVersion = 4
|
||||
case dnsmessage.TypeAAAA:
|
||||
case mDNS.TypeAAAA:
|
||||
metadata.IPVersion = 6
|
||||
}
|
||||
metadata.Domain = string(message.Questions[0].Name.Data[:message.Questions[0].Name.Length-1])
|
||||
metadata.Domain = fqdnToDomain(message.Question[0].Name)
|
||||
}
|
||||
ctx, transport, strategy := r.matchDNS(ctx)
|
||||
ctx, cancel := context.WithTimeout(ctx, C.DNSTimeout)
|
||||
defer cancel()
|
||||
response, err := r.dnsClient.Exchange(ctx, transport, message, strategy)
|
||||
if err != nil && len(message.Questions) > 0 {
|
||||
r.dnsLogger.ErrorContext(ctx, E.Cause(err, "exchange failed for ", message.Questions[0].Name.String()))
|
||||
if err != nil && len(message.Question) > 0 {
|
||||
r.dnsLogger.ErrorContext(ctx, E.Cause(err, "exchange failed for ", formatQuestion(message.Question[0].String())))
|
||||
}
|
||||
if len(message.Questions) > 0 && response != nil {
|
||||
LogDNSAnswers(r.dnsLogger, ctx, message.Questions[0].Name.String(), response.Answers)
|
||||
if len(message.Question) > 0 && response != nil {
|
||||
LogDNSAnswers(r.dnsLogger, ctx, message.Question[0].Name, response.Answer)
|
||||
}
|
||||
return response, err
|
||||
}
|
||||
|
@ -93,61 +93,26 @@ func (r *Router) LookupDefault(ctx context.Context, domain string) ([]netip.Addr
|
|||
return r.Lookup(ctx, domain, dns.DomainStrategyAsIS)
|
||||
}
|
||||
|
||||
func LogDNSAnswers(logger log.ContextLogger, ctx context.Context, domain string, answers []dnsmessage.Resource) {
|
||||
for _, rawAnswer := range answers {
|
||||
var content string
|
||||
switch answer := rawAnswer.Body.(type) {
|
||||
case *dnsmessage.AResource:
|
||||
content = netip.AddrFrom4(answer.A).String()
|
||||
case *dnsmessage.NSResource:
|
||||
content = answer.NS.String()
|
||||
case *dnsmessage.CNAMEResource:
|
||||
content = answer.CNAME.String()
|
||||
case *dnsmessage.SOAResource:
|
||||
content = answer.MBox.String()
|
||||
case *dnsmessage.PTRResource:
|
||||
content = answer.PTR.String()
|
||||
case *dnsmessage.MXResource:
|
||||
content = answer.MX.String()
|
||||
case *dnsmessage.TXTResource:
|
||||
content = strings.Join(answer.TXT, " ")
|
||||
case *dnsmessage.AAAAResource:
|
||||
content = netip.AddrFrom16(answer.AAAA).String()
|
||||
case *dnsmessage.SRVResource:
|
||||
content = answer.Target.String()
|
||||
case *dnsmessage.UnknownResource:
|
||||
content = answer.Type.String()
|
||||
default:
|
||||
continue
|
||||
}
|
||||
rType := formatDNSType(rawAnswer.Header.Type)
|
||||
if rType == "" {
|
||||
logger.InfoContext(ctx, "exchanged ", domain, " ", rType)
|
||||
} else {
|
||||
logger.InfoContext(ctx, "exchanged ", domain, " ", rType, " ", content)
|
||||
}
|
||||
func LogDNSAnswers(logger log.ContextLogger, ctx context.Context, domain string, answers []mDNS.RR) {
|
||||
for _, answer := range answers {
|
||||
logger.InfoContext(ctx, "exchanged ", domain, " ", mDNS.Type(answer.Header().Rrtype).String(), " ", formatQuestion(answer.String()))
|
||||
}
|
||||
}
|
||||
|
||||
func formatDNSQuestion(question dnsmessage.Question) string {
|
||||
var qType string
|
||||
qType = question.Type.String()
|
||||
if len(qType) > 4 {
|
||||
qType = qType[4:]
|
||||
func fqdnToDomain(fqdn string) string {
|
||||
if mDNS.IsFqdn(fqdn) {
|
||||
return fqdn[:len(fqdn)-1]
|
||||
}
|
||||
var qClass string
|
||||
qClass = question.Class.String()
|
||||
if len(qClass) > 5 {
|
||||
qClass = qClass[5:]
|
||||
}
|
||||
return string(question.Name.Data[:question.Name.Length-1]) + " " + qType + " " + qClass
|
||||
return fqdn
|
||||
}
|
||||
|
||||
func formatDNSType(qType dnsmessage.Type) string {
|
||||
qTypeName := qType.String()
|
||||
if len(qTypeName) > 4 {
|
||||
return qTypeName[4:]
|
||||
} else {
|
||||
return F.ToString("unknown (type ", qTypeName, ")")
|
||||
func formatQuestion(string string) string {
|
||||
if strings.HasPrefix(string, ";") {
|
||||
string = string[1:]
|
||||
}
|
||||
string = strings.ReplaceAll(string, "\t", " ")
|
||||
for strings.Contains(string, " ") {
|
||||
string = strings.ReplaceAll(string, " ", " ")
|
||||
}
|
||||
return string
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue