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))
 }