Files
waf-platform/EdgeAdmin/internal/utils/lookup.go
2026-02-24 11:33:44 +08:00

93 lines
2.0 KiB
Go

package utils
import (
"errors"
"sync"
"github.com/iwind/TeaGo/lists"
"github.com/iwind/TeaGo/logs"
"github.com/miekg/dns"
)
var dnsClient *dns.Client
var dnsConfig *dns.ClientConfig
func init() {
// The teaconst.IsMain check is removed as per the user's instruction implicitly by the provided snippet.
// if !teaconst.IsMain {
// return
// }
config, err := dns.ClientConfigFromFile("/etc/resolv.conf")
if err != nil {
// Fallback for Windows or systems without resolv.conf
config = &dns.ClientConfig{
Servers: []string{"8.8.8.8", "8.8.4.4"},
Search: []string{},
Port: "53",
Ndots: 1,
Timeout: 5,
Attempts: 2,
}
logs.Println("WARNING: configure dns client: /etc/resolv.conf not found, using fallback 8.8.8.8")
}
dnsConfig = config
dnsClient = new(dns.Client)
}
// LookupCNAME 获取CNAME
func LookupCNAME(host string) (string, error) {
if dnsClient == nil || dnsConfig == nil {
return "", errors.New("dns client not initialized")
}
m := new(dns.Msg)
m.SetQuestion(dns.Fqdn(host), dns.TypeCNAME)
m.RecursionDesired = true
var serverAddrs = dnsConfig.Servers
{
var publicDNSHosts = []string{"8.8.8.8" /** Google **/, "8.8.4.4" /** Google **/}
for _, publicDNSHost := range publicDNSHosts {
if !lists.ContainsString(serverAddrs, publicDNSHost) {
serverAddrs = append(serverAddrs, publicDNSHost)
}
}
}
var wg = &sync.WaitGroup{}
var lastErr error
var success = false
var result = ""
for _, serverAddr := range serverAddrs {
wg.Add(1)
go func(server string) {
defer wg.Done()
r, _, err := dnsClient.Exchange(m, server+":"+dnsConfig.Port)
if err == nil && r != nil && r.Rcode == dns.RcodeSuccess {
for _, ans := range r.Answer {
if cname, ok := ans.(*dns.CNAME); ok {
success = true
result = cname.Target
}
}
} else if err != nil {
lastErr = err
}
}(serverAddr)
}
wg.Wait()
if success {
return result, nil
}
if lastErr != nil {
return "", lastErr
}
return "", errors.New("lookup failed")
}