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  }