From c80646a045c2d8b2d7d68a63036f21c37c4c1c0d Mon Sep 17 00:00:00 2001 From: yuhan6665 <1588741+yuhan6665@users.noreply.github.com> Date: Sat, 20 May 2023 23:40:56 -0400 Subject: [PATCH] Clean code dependencies on github.com/miekg/dns (#2099) --- transport/internet/headers/dns/dns.go | 71 ++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/transport/internet/headers/dns/dns.go b/transport/internet/headers/dns/dns.go index a7366d1a..df209ff6 100644 --- a/transport/internet/headers/dns/dns.go +++ b/transport/internet/headers/dns/dns.go @@ -3,8 +3,8 @@ package dns import ( "context" "encoding/binary" + "errors" - "github.com/miekg/dns" "github.com/xtls/xray-core/common" "github.com/xtls/xray-core/common/dice" ) @@ -36,7 +36,7 @@ func NewDNS(ctx context.Context, config interface{}) (interface{}, error) { buf := make([]byte, 0x100) - off1, err := dns.PackDomainName(dns.Fqdn(config.(*Config).Domain), buf, 0, nil, false) + off1, err := packDomainName(config.(*Config).Domain + ".", buf) if err != nil { return nil, err } @@ -51,6 +51,73 @@ func NewDNS(ctx context.Context, config interface{}) (interface{}, error) { }, nil } +// copied from github.com/miekg/dns +func packDomainName(s string, msg []byte) (off1 int, err error) { + off := 0 + ls := len(s) + // Each dot ends a segment of the name. + // We trade each dot byte for a length byte. + // Except for escaped dots (\.), which are normal dots. + // There is also a trailing zero. + + // Emit sequence of counted strings, chopping at dots. + var ( + begin int + bs []byte + ) + for i := 0; i < ls; i++ { + var c byte + if bs == nil { + c = s[i] + } else { + c = bs[i] + } + + switch c { + case '\\': + if off+1 > len(msg) { + return len(msg), errors.New("buffer size too small") + } + + if bs == nil { + bs = []byte(s) + } + + copy(bs[i:ls-1], bs[i+1:]) + ls-- + case '.': + labelLen := i - begin + if labelLen >= 1<<6 { // top two bits of length must be clear + return len(msg), errors.New("bad rdata") + } + + // off can already (we're in a loop) be bigger than len(msg) + // this happens when a name isn't fully qualified + if off+1+labelLen > len(msg) { + return len(msg), errors.New("buffer size too small") + } + + // The following is covered by the length check above. + msg[off] = byte(labelLen) + + if bs == nil { + copy(msg[off+1:], s[begin:i]) + } else { + copy(msg[off+1:], bs[begin:i]) + } + off += 1 + labelLen + begin = i + 1 + default: + } + } + + if off < len(msg) { + msg[off] = 0 + } + + return off + 1, nil +} + func init() { common.Must(common.RegisterConfig((*Config)(nil), NewDNS)) }