github.com/chwjbn/xclash@v0.2.0/dns/util.go (about) 1 package dns 2 3 import ( 4 "crypto/tls" 5 "net" 6 "time" 7 8 "github.com/chwjbn/xclash/common/cache" 9 "github.com/chwjbn/xclash/log" 10 11 D "github.com/miekg/dns" 12 ) 13 14 func putMsgToCache(c *cache.LruCache, key string, msg *D.Msg) { 15 var ttl uint32 16 switch { 17 case len(msg.Answer) != 0: 18 ttl = msg.Answer[0].Header().Ttl 19 case len(msg.Ns) != 0: 20 ttl = msg.Ns[0].Header().Ttl 21 case len(msg.Extra) != 0: 22 ttl = msg.Extra[0].Header().Ttl 23 default: 24 log.Debugln("[DNS] response msg empty: %#v", msg) 25 return 26 } 27 28 c.SetWithExpire(key, msg.Copy(), time.Now().Add(time.Second*time.Duration(ttl))) 29 } 30 31 func setMsgTTL(msg *D.Msg, ttl uint32) { 32 for _, answer := range msg.Answer { 33 answer.Header().Ttl = ttl 34 } 35 36 for _, ns := range msg.Ns { 37 ns.Header().Ttl = ttl 38 } 39 40 for _, extra := range msg.Extra { 41 extra.Header().Ttl = ttl 42 } 43 } 44 45 func isIPRequest(q D.Question) bool { 46 return q.Qclass == D.ClassINET && (q.Qtype == D.TypeA || q.Qtype == D.TypeAAAA) 47 } 48 49 func transform(servers []NameServer, resolver *Resolver) []dnsClient { 50 ret := []dnsClient{} 51 for _, s := range servers { 52 switch s.Net { 53 case "https": 54 ret = append(ret, newDoHClient(s.Addr, resolver)) 55 continue 56 case "dhcp": 57 ret = append(ret, newDHCPClient(s.Addr)) 58 continue 59 } 60 61 host, port, _ := net.SplitHostPort(s.Addr) 62 ret = append(ret, &client{ 63 Client: &D.Client{ 64 Net: s.Net, 65 TLSConfig: &tls.Config{ 66 // alpn identifier, see https://tools.ietf.org/html/draft-hoffman-dprive-dns-tls-alpn-00#page-6 67 NextProtos: []string{"dns"}, 68 ServerName: host, 69 }, 70 UDPSize: 4096, 71 Timeout: 5 * time.Second, 72 }, 73 port: port, 74 host: host, 75 iface: s.Interface, 76 r: resolver, 77 }) 78 } 79 return ret 80 } 81 82 func handleMsgWithEmptyAnswer(r *D.Msg) *D.Msg { 83 msg := &D.Msg{} 84 msg.Answer = []D.RR{} 85 86 msg.SetRcode(r, D.RcodeSuccess) 87 msg.Authoritative = true 88 msg.RecursionAvailable = true 89 90 return msg 91 } 92 93 func msgToIP(msg *D.Msg) []net.IP { 94 ips := []net.IP{} 95 96 for _, answer := range msg.Answer { 97 switch ans := answer.(type) { 98 case *D.AAAA: 99 ips = append(ips, ans.AAAA) 100 case *D.A: 101 ips = append(ips, ans.A) 102 } 103 } 104 105 return ips 106 }