From bd8d198fe5009b9d4a3bfc6ba7d6c7013195cfa7 Mon Sep 17 00:00:00 2001 From: lirui Date: Sun, 4 Jan 2026 22:37:17 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96DoH=E8=AF=B7=E6=B1=82?= =?UTF-8?q?=E5=A4=84=E7=90=86=EF=BC=8C=E4=BD=BF=E7=94=A8HTTP=20POST?= =?UTF-8?q?=E5=8F=91=E9=80=81DNS=E6=B6=88=E6=81=AF=E5=B9=B6=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E5=93=8D=E5=BA=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/dns/dns.go | 49 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/internal/dns/dns.go b/internal/dns/dns.go index 8b6c9b1..f13880e 100644 --- a/internal/dns/dns.go +++ b/internal/dns/dns.go @@ -1,9 +1,11 @@ package dns import ( + "bytes" "context" "crypto/tls" "fmt" + "io" "net/http" "sync" "time" @@ -142,17 +144,46 @@ func (s *DNSServer) forwardDoH(req *dns.Msg) (*dns.Msg, error) { ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) defer cancel() - // 使用 DNS-over-HTTPS 客户端 - client := &dns.Client{ - Net: "https", - TLSConfig: &tls.Config{ - InsecureSkipVerify: false, - }, - Timeout: 3 * time.Second, + // 将 DNS 消息打包 + packed, err := req.Pack() + if err != nil { + return nil, err } - resp, _, err := client.ExchangeContext(ctx, req, s.DoHURL) - return resp, err + // 创建 HTTP POST 请求 + httpReq, err := http.NewRequestWithContext(ctx, "POST", s.DoHURL, bytes.NewReader(packed)) + if err != nil { + return nil, err + } + + // 设置 DoH 请求头 + httpReq.Header.Set("Content-Type", "application/dns-message") + httpReq.Header.Set("Accept", "application/dns-message") + + // 发送请求 + resp, err := s.httpClient.Do(httpReq) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("DoH server returned status %d", resp.StatusCode) + } + + // 读取响应 + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + // 解析 DNS 响应 + dnsResp := new(dns.Msg) + if err := dnsResp.Unpack(body); err != nil { + return nil, err + } + + return dnsResp, nil } // recordQuery 记录DNS查询