|
|
@ -15,13 +15,8 @@ import (
|
|
|
|
"tailscale.com/tstest"
|
|
|
|
"tailscale.com/tstest"
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
var testipv4 = netaddr.IPv4(1, 2, 3, 4)
|
|
|
|
var testipv4 = netaddr.MustParseIP("1.2.3.4")
|
|
|
|
var testipv6 = netaddr.IPv6Raw([16]byte{
|
|
|
|
var testipv6 = netaddr.MustParseIP("0001:0203:0405:0607:0809:0a0b:0c0d:0e0f")
|
|
|
|
0x00, 0x01, 0x02, 0x03,
|
|
|
|
|
|
|
|
0x04, 0x05, 0x06, 0x07,
|
|
|
|
|
|
|
|
0x08, 0x09, 0x0a, 0x0b,
|
|
|
|
|
|
|
|
0x0c, 0x0d, 0x0e, 0x0f,
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var dnsCfg = Config{
|
|
|
|
var dnsCfg = Config{
|
|
|
|
Hosts: map[string][]netaddr.IP{
|
|
|
|
Hosts: map[string][]netaddr.IP{
|
|
|
@ -283,32 +278,14 @@ func TestDelegate(t *testing.T) {
|
|
|
|
t.Skip("skipping test that requires localhost IPv6")
|
|
|
|
t.Skip("skipping test that requires localhost IPv6")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
dnsHandleFunc("test.site.", resolveToIP(testipv4, testipv6, "dns.test.site."))
|
|
|
|
v4server := serveDNS(t, "127.0.0.1:0",
|
|
|
|
dnsHandleFunc("nxdomain.site.", resolveToNXDOMAIN)
|
|
|
|
"test.site.", resolveToIP(testipv4, testipv6, "dns.test.site."),
|
|
|
|
|
|
|
|
"nxdomain.site.", resolveToNXDOMAIN)
|
|
|
|
v4server, v4errch := serveDNS(t, "127.0.0.1:0")
|
|
|
|
defer v4server.Shutdown()
|
|
|
|
v6server, v6errch := serveDNS(t, "[::1]:0")
|
|
|
|
v6server := serveDNS(t, "[::1]:0",
|
|
|
|
|
|
|
|
"test.site.", resolveToIP(testipv4, testipv6, "dns.test.site."),
|
|
|
|
defer func() {
|
|
|
|
"nxdomain.site.", resolveToNXDOMAIN)
|
|
|
|
if err := <-v4errch; err != nil {
|
|
|
|
defer v6server.Shutdown()
|
|
|
|
t.Errorf("v4 server error: %v", err)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := <-v6errch; err != nil {
|
|
|
|
|
|
|
|
t.Errorf("v6 server error: %v", err)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
if v4server != nil {
|
|
|
|
|
|
|
|
defer v4server.Shutdown()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if v6server != nil {
|
|
|
|
|
|
|
|
defer v6server.Shutdown()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if v4server == nil || v6server == nil {
|
|
|
|
|
|
|
|
// There is an error in at least one of the channels
|
|
|
|
|
|
|
|
// and we cannot proceed; return to see it.
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
r, err := New(t.Logf, nil)
|
|
|
|
r, err := New(t.Logf, nil)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
@ -377,19 +354,75 @@ func TestDelegate(t *testing.T) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func TestDelegateCollision(t *testing.T) {
|
|
|
|
func TestDelegateSplitRoute(t *testing.T) {
|
|
|
|
dnsHandleFunc("test.site.", resolveToIP(testipv4, testipv6, "dns.test.site."))
|
|
|
|
test4 := netaddr.MustParseIP("2.3.4.5")
|
|
|
|
|
|
|
|
test6 := netaddr.MustParseIP("ff::1")
|
|
|
|
|
|
|
|
|
|
|
|
server, errch := serveDNS(t, "127.0.0.1:0")
|
|
|
|
server1 := serveDNS(t, "127.0.0.1:0",
|
|
|
|
defer func() {
|
|
|
|
"test.site.", resolveToIP(testipv4, testipv6, "dns.test.site."))
|
|
|
|
if err := <-errch; err != nil {
|
|
|
|
defer server1.Shutdown()
|
|
|
|
t.Errorf("server error: %v", err)
|
|
|
|
server2 := serveDNS(t, "127.0.0.1:0",
|
|
|
|
}
|
|
|
|
"test.other.", resolveToIP(test4, test6, "dns.other."))
|
|
|
|
}()
|
|
|
|
defer server2.Shutdown()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
r, err := New(t.Logf, nil)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
t.Fatalf("start: %v", err)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
defer r.Close()
|
|
|
|
|
|
|
|
|
|
|
|
if server == nil {
|
|
|
|
cfg := dnsCfg
|
|
|
|
return
|
|
|
|
cfg.Routes = map[string][]netaddr.IPPort{
|
|
|
|
|
|
|
|
".": {netaddr.MustParseIPPort(server1.PacketConn.LocalAddr().String())},
|
|
|
|
|
|
|
|
"other.": {netaddr.MustParseIPPort(server2.PacketConn.LocalAddr().String())},
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
r.SetConfig(cfg)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
|
|
|
|
title string
|
|
|
|
|
|
|
|
query []byte
|
|
|
|
|
|
|
|
response dnsResponse
|
|
|
|
|
|
|
|
}{
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"general",
|
|
|
|
|
|
|
|
dnspacket("test.site.", dns.TypeA),
|
|
|
|
|
|
|
|
dnsResponse{ip: testipv4, rcode: dns.RCodeSuccess},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
"override",
|
|
|
|
|
|
|
|
dnspacket("test.other.", dns.TypeA),
|
|
|
|
|
|
|
|
dnsResponse{ip: test4, rcode: dns.RCodeSuccess},
|
|
|
|
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
|
|
|
|
t.Run(tt.title, func(t *testing.T) {
|
|
|
|
|
|
|
|
payload, err := syncRespond(r, tt.query)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
t.Errorf("err = %v; want nil", err)
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
response, err := unpackResponse(payload)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
t.Errorf("extract: err = %v; want nil (in %x)", err, payload)
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if response.rcode != tt.response.rcode {
|
|
|
|
|
|
|
|
t.Errorf("rcode = %v; want %v", response.rcode, tt.response.rcode)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if response.ip != tt.response.ip {
|
|
|
|
|
|
|
|
t.Errorf("ip = %v; want %v", response.ip, tt.response.ip)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if response.name != tt.response.name {
|
|
|
|
|
|
|
|
t.Errorf("name = %v; want %v", response.name, tt.response.name)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func TestDelegateCollision(t *testing.T) {
|
|
|
|
|
|
|
|
server := serveDNS(t, "127.0.0.1:0",
|
|
|
|
|
|
|
|
"test.site.", resolveToIP(testipv4, testipv6, "dns.test.site."))
|
|
|
|
defer server.Shutdown()
|
|
|
|
defer server.Shutdown()
|
|
|
|
|
|
|
|
|
|
|
|
r, err := New(t.Logf, nil)
|
|
|
|
r, err := New(t.Logf, nil)
|
|
|
@ -628,8 +661,8 @@ func TestFull(t *testing.T) {
|
|
|
|
{"ipv6", dnspacket("test2.ipn.dev.", dns.TypeAAAA), ipv6Response},
|
|
|
|
{"ipv6", dnspacket("test2.ipn.dev.", dns.TypeAAAA), ipv6Response},
|
|
|
|
{"no-ipv6", dnspacket("test1.ipn.dev.", dns.TypeAAAA), emptyResponse},
|
|
|
|
{"no-ipv6", dnspacket("test1.ipn.dev.", dns.TypeAAAA), emptyResponse},
|
|
|
|
{"upper", dnspacket("TEST1.IPN.DEV.", dns.TypeA), ipv4UppercaseResponse},
|
|
|
|
{"upper", dnspacket("TEST1.IPN.DEV.", dns.TypeA), ipv4UppercaseResponse},
|
|
|
|
{"ptr", dnspacket("4.3.2.1.in-addr.arpa.", dns.TypePTR), ptrResponse},
|
|
|
|
{"ptr4", dnspacket("4.3.2.1.in-addr.arpa.", dns.TypePTR), ptrResponse},
|
|
|
|
{"ptr", dnspacket("f.0.e.0.d.0.c.0.b.0.a.0.9.0.8.0.7.0.6.0.5.0.4.0.3.0.2.0.1.0.0.0.ip6.arpa.",
|
|
|
|
{"ptr6", dnspacket("f.0.e.0.d.0.c.0.b.0.a.0.9.0.8.0.7.0.6.0.5.0.4.0.3.0.2.0.1.0.0.0.ip6.arpa.",
|
|
|
|
dns.TypePTR), ptrResponse6},
|
|
|
|
dns.TypePTR), ptrResponse6},
|
|
|
|
{"nxdomain", dnspacket("test3.ipn.dev.", dns.TypeA), nxdomainResponse},
|
|
|
|
{"nxdomain", dnspacket("test3.ipn.dev.", dns.TypeA), nxdomainResponse},
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -702,18 +735,8 @@ func TestTrimRDNSBonjourPrefix(t *testing.T) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func BenchmarkFull(b *testing.B) {
|
|
|
|
func BenchmarkFull(b *testing.B) {
|
|
|
|
dnsHandleFunc("test.site.", resolveToIP(testipv4, testipv6, "dns.test.site."))
|
|
|
|
server := serveDNS(b, "127.0.0.1:0",
|
|
|
|
|
|
|
|
"test.site.", resolveToIP(testipv4, testipv6, "dns.test.site."))
|
|
|
|
server, errch := serveDNS(b, "127.0.0.1:0")
|
|
|
|
|
|
|
|
defer func() {
|
|
|
|
|
|
|
|
if err := <-errch; err != nil {
|
|
|
|
|
|
|
|
b.Errorf("server error: %v", err)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if server == nil {
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
defer server.Shutdown()
|
|
|
|
defer server.Shutdown()
|
|
|
|
|
|
|
|
|
|
|
|
r, err := New(b.Logf, nil)
|
|
|
|
r, err := New(b.Logf, nil)
|
|
|
|