优化DoH请求处理,使用HTTP POST发送DNS消息并解析响应

This commit is contained in:
lirui
2026-01-04 22:37:17 +08:00
parent 27d53c8751
commit bd8d198fe5

View File

@@ -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查询