github.com/yaling888/clash@v1.53.0/listener/tun/ipstack/commons/dns.go (about) 1 package commons 2 3 import ( 4 "net/netip" 5 "time" 6 7 D "github.com/miekg/dns" 8 9 "github.com/yaling888/clash/component/resolver" 10 C "github.com/yaling888/clash/constant" 11 ) 12 13 const ipv6Delay = time.Millisecond * 6 // delay response AAAA answer when disable IPv6 14 15 func ShouldHijackDns(dnsHijack []C.DNSUrl, targetAddr netip.AddrPort, network string) bool { 16 for _, dns := range dnsHijack { 17 if dns.Network == network && (dns.AddrPort.AddrPort == targetAddr || 18 (dns.AddrPort.Addr().IsUnspecified() && dns.AddrPort.Port() == targetAddr.Port())) { 19 return true 20 } 21 } 22 return false 23 } 24 25 func RelayDnsPacket(payload []byte) ([]byte, error) { 26 msg := &D.Msg{} 27 if err := msg.Unpack(payload); err != nil { 28 return nil, err 29 } 30 31 if len(msg.Question) == 0 { 32 return handleMsgWithEmptyAnswer(msg, D.RcodeBadName) 33 } 34 35 if resolver.DisableIPv6 && msg.Question[0].Qtype == D.TypeAAAA { 36 time.Sleep(ipv6Delay) 37 return handleMsgWithEmptyAnswer(msg, D.RcodeSuccess) 38 } 39 40 r, err := resolver.ServeMsg(msg) 41 if err != nil { 42 return handleMsgWithEmptyAnswer(msg, D.RcodeServerFailure) 43 } 44 45 r.SetRcode(msg, r.Rcode) 46 r.Compress = true 47 return r.Pack() 48 } 49 50 func handleMsgWithEmptyAnswer(r *D.Msg, code int) ([]byte, error) { 51 msg := &D.Msg{} 52 msg.Answer = []D.RR{} 53 54 msg.SetRcode(r, code) 55 msg.Authoritative = true 56 msg.RecursionAvailable = true 57 58 return msg.Pack() 59 }