FILE / ScuroNeko/mtg

network/v2/dns.go

Исходный файл и его история в репозитории.
FILE d32e8e8b9731b6edb83c0ec9211bca9ec63913ab
Files
mtg/network/v2/dns.go
T

62 lines
1.2 KiB
Go

package network
import (
"context"
"fmt"
"net"
"net/url"
"time"
"github.com/ncruces/go-dns"
)
var dnsCacheOptions = []dns.CacheOption{
dns.MaxCacheEntries(dns.DefaultMaxCacheEntries),
dns.MaxCacheTTL(time.Hour),
dns.NegativeCache(false),
}
func GetDNS(u *url.URL) (*net.Resolver, error) {
if u == nil {
return dns.NewCachingResolver(nil, dnsCacheOptions...), nil
}
if u.Scheme == "" {
u.Scheme = "udp"
}
if u.Scheme == "udp" && u.Host == "" {
u.Host = u.Path
u.Path = ""
}
switch u.Scheme {
case "tls":
return dns.NewDoTResolver(u.Host, dns.DoTCache(dnsCacheOptions...))
case "https":
if u.Path == "" {
u.Path = "/dns-query"
}
return dns.NewDoHResolver(u.String(), dns.DoHCache(dnsCacheOptions...))
case "udp", "":
default:
return nil, fmt.Errorf("unsupported DNS %v", u)
}
port := u.Port()
if port == "" {
port = "53"
}
hostport := net.JoinHostPort(u.Hostname(), port)
dialer := &net.Dialer{}
resolver := &net.Resolver{
PreferGo: true,
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
return dialer.DialContext(ctx, "udp", hostport)
},
}
return dns.NewCachingResolver(resolver, dnsCacheOptions...), nil
}