net/dns/resolver: add Windows ExitDNS service support, using net package
Updates #1713 Updates #835 Change-Id: Ia71e96d0632c2d617b401695ad68301b07c1c2ec Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:

committed by
Brad Fitzpatrick

parent
cab5c46481
commit
cced414c7d
@ -6,6 +6,7 @@ package resolver
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@ -179,6 +180,129 @@ var resolveToNXDOMAIN = dns.HandlerFunc(func(w dns.ResponseWriter, req *dns.Msg)
|
||||
w.WriteMsg(m)
|
||||
})
|
||||
|
||||
// weirdoGoCNAMEHandler returns a DNS handler that satisfies
|
||||
// Go's weird Resolver.LookupCNAME (read its godoc carefully!).
|
||||
//
|
||||
// This doesn't even return a CNAME record, because that's not
|
||||
// what Go looks for.
|
||||
func weirdoGoCNAMEHandler(target string) dns.HandlerFunc {
|
||||
return func(w dns.ResponseWriter, req *dns.Msg) {
|
||||
m := new(dns.Msg)
|
||||
m.SetReply(req)
|
||||
question := req.Question[0]
|
||||
|
||||
switch question.Qtype {
|
||||
case dns.TypeA:
|
||||
m.Answer = append(m.Answer, &dns.CNAME{
|
||||
Hdr: dns.RR_Header{
|
||||
Name: target,
|
||||
Rrtype: dns.TypeCNAME,
|
||||
Class: dns.ClassINET,
|
||||
Ttl: 600,
|
||||
},
|
||||
Target: target,
|
||||
})
|
||||
case dns.TypeAAAA:
|
||||
m.Answer = append(m.Answer, &dns.AAAA{
|
||||
Hdr: dns.RR_Header{
|
||||
Name: target,
|
||||
Rrtype: dns.TypeAAAA,
|
||||
Class: dns.ClassINET,
|
||||
Ttl: 600,
|
||||
},
|
||||
AAAA: net.ParseIP("1::2"),
|
||||
})
|
||||
}
|
||||
w.WriteMsg(m)
|
||||
}
|
||||
}
|
||||
|
||||
// dnsHandler returns a handler that replies with the answers/options
|
||||
// provided.
|
||||
//
|
||||
// Types supported: netaddr.IP.
|
||||
func dnsHandler(answers ...interface{}) dns.HandlerFunc {
|
||||
return func(w dns.ResponseWriter, req *dns.Msg) {
|
||||
m := new(dns.Msg)
|
||||
m.SetReply(req)
|
||||
if len(req.Question) != 1 {
|
||||
panic("not a single-question request")
|
||||
}
|
||||
m.RecursionAvailable = true // to stop net package's errLameReferral on empty replies
|
||||
|
||||
question := req.Question[0]
|
||||
for _, a := range answers {
|
||||
switch a := a.(type) {
|
||||
default:
|
||||
panic(fmt.Sprintf("unsupported dnsHandler arg %T", a))
|
||||
case netaddr.IP:
|
||||
ip := a
|
||||
if ip.Is4() {
|
||||
m.Answer = append(m.Answer, &dns.A{
|
||||
Hdr: dns.RR_Header{
|
||||
Name: question.Name,
|
||||
Rrtype: dns.TypeA,
|
||||
Class: dns.ClassINET,
|
||||
},
|
||||
A: ip.IPAddr().IP,
|
||||
})
|
||||
} else if ip.Is6() {
|
||||
m.Answer = append(m.Answer, &dns.AAAA{
|
||||
Hdr: dns.RR_Header{
|
||||
Name: question.Name,
|
||||
Rrtype: dns.TypeAAAA,
|
||||
Class: dns.ClassINET,
|
||||
},
|
||||
AAAA: ip.IPAddr().IP,
|
||||
})
|
||||
}
|
||||
case dns.PTR:
|
||||
ptr := a
|
||||
ptr.Hdr = dns.RR_Header{
|
||||
Name: question.Name,
|
||||
Rrtype: dns.TypePTR,
|
||||
Class: dns.ClassINET,
|
||||
}
|
||||
m.Answer = append(m.Answer, &ptr)
|
||||
case dns.CNAME:
|
||||
c := a
|
||||
c.Hdr = dns.RR_Header{
|
||||
Name: question.Name,
|
||||
Rrtype: dns.TypeCNAME,
|
||||
Class: dns.ClassINET,
|
||||
Ttl: 600,
|
||||
}
|
||||
m.Answer = append(m.Answer, &c)
|
||||
case dns.TXT:
|
||||
txt := a
|
||||
txt.Hdr = dns.RR_Header{
|
||||
Name: question.Name,
|
||||
Rrtype: dns.TypeTXT,
|
||||
Class: dns.ClassINET,
|
||||
}
|
||||
m.Answer = append(m.Answer, &txt)
|
||||
case dns.SRV:
|
||||
srv := a
|
||||
srv.Hdr = dns.RR_Header{
|
||||
Name: question.Name,
|
||||
Rrtype: dns.TypeSRV,
|
||||
Class: dns.ClassINET,
|
||||
}
|
||||
m.Answer = append(m.Answer, &srv)
|
||||
case dns.NS:
|
||||
rr := a
|
||||
rr.Hdr = dns.RR_Header{
|
||||
Name: question.Name,
|
||||
Rrtype: dns.TypeNS,
|
||||
Class: dns.ClassINET,
|
||||
}
|
||||
m.Answer = append(m.Answer, &rr)
|
||||
}
|
||||
}
|
||||
w.WriteMsg(m)
|
||||
}
|
||||
}
|
||||
|
||||
func serveDNS(tb testing.TB, addr string, records ...interface{}) *dns.Server {
|
||||
if len(records)%2 != 0 {
|
||||
panic("must have an even number of record values")
|
||||
|
Reference in New Issue
Block a user