Skip to content
This repository has been archived by the owner on Jun 20, 2024. It is now read-only.

Commit

Permalink
Test for recursive DNS queries & compression.
Browse files Browse the repository at this point in the history
Note this doesn't test the golang resolver, where the original error
was found, as I can't find a way to point the golang resolver at a
custom dns server during a test.  It does check that a compressed
response from an upstream server is correctly handled.
  • Loading branch information
Tom Wilkie authored and rade committed Aug 17, 2015
1 parent 4f00dab commit 67f9749
Showing 1 changed file with 80 additions and 5 deletions.
85 changes: 80 additions & 5 deletions nameserver/dns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"math/rand"
"net"
"strconv"
"testing"
"time"

Expand All @@ -14,9 +15,7 @@ import (
"github.com/weaveworks/weave/router"
)

func TestTruncation(t *testing.T) {
//common.SetLogLevel("debug")

func startServer(t *testing.T) (*DNSServer, *Nameserver, int, int) {
peername, err := router.PeerNameFromString("00:00:00:02:00:00")
require.Nil(t, err)
nameserver := New(peername, nil, nil, "")
Expand All @@ -25,13 +24,19 @@ func TestTruncation(t *testing.T) {
udpPort := dnsserver.servers[0].PacketConn.LocalAddr().(*net.UDPAddr).Port
tcpPort := dnsserver.servers[1].Listener.Addr().(*net.TCPAddr).Port
go dnsserver.ActivateAndServe()
return dnsserver, nameserver, udpPort, tcpPort
}

func TestTruncation(t *testing.T) {
//common.SetLogLevel("debug")
dnsserver, nameserver, udpPort, tcpPort := startServer(t)
defer dnsserver.Stop()

// Add 100 mappings to nameserver
addrs := []address.Address{}
for i := address.Address(0); i < 100; i++ {
addrs = append(addrs, i)
nameserver.AddEntry("foo.weave.local.", "", peername, i)
nameserver.AddEntry("foo.weave.local.", "", router.UnknownPeerName, i)
}

doRequest := func(client *dns.Client, request *dns.Msg, port int) *dns.Msg {
Expand All @@ -45,7 +50,6 @@ func TestTruncation(t *testing.T) {
{
udpClient := dns.Client{Net: "udp", UDPSize: minUDPSize}
response := doRequest(&udpClient, &dns.Msg{}, udpPort)
require.Nil(t, err)
require.True(t, response.MsgHdr.Truncated)
require.True(t, len(response.Answer) < 100)
}
Expand Down Expand Up @@ -93,3 +97,74 @@ func TestTruncateResponse(t *testing.T) {
require.True(t, response.Len() <= maxSize)
}
}

func TestRecursiveCompress(t *testing.T) {
const (
hostname = "foo.example."
maxSize = 512
)

// Construct a response that is >512 when uncompressed, <512 when compressed
response := dns.Msg{}
response.Authoritative = true
response.Answer = []dns.RR{}
header := dns.RR_Header{
Name: hostname,
Rrtype: dns.TypeA,
Class: dns.ClassINET,
Ttl: 10,
}
for response.Len() <= maxSize {
ip := address.Address(rand.Uint32()).IP4()
response.Answer = append(response.Answer, &dns.A{Hdr: header, A: ip})
}
response.Compress = true
require.True(t, response.Len() <= maxSize)

// A dns server that returns the above response
var gotRequest = false
handleRecursive := func(w dns.ResponseWriter, req *dns.Msg) {
gotRequest = true
require.Equal(t, req.Question[0].Name, hostname)
response.SetReply(req)
err := w.WriteMsg(&response)
require.Nil(t, err)
}
mux := dns.NewServeMux()
mux.HandleFunc(topDomain, handleRecursive)
udpListener, err := net.ListenPacket("udp", "0.0.0.0:0")
require.Nil(t, err)
udpServer := &dns.Server{PacketConn: udpListener, Handler: mux}
udpServerPort := udpListener.LocalAddr().(*net.UDPAddr).Port
go udpServer.ActivateAndServe()
defer udpServer.Shutdown()

// The weavedns server, pointed at the above server
dnsserver, _, udpPort, _ := startServer(t)
dnsserver.upstream = &dns.ClientConfig{
Servers: []string{"127.0.0.1"},
Port: strconv.Itoa(udpServerPort),
Ndots: 1,
Timeout: 5,
Attempts: 2,
}
defer dnsserver.Stop()

// Now do lookup, check its what we expected.
// NB this doesn't really test golang's resolver behaves correctly, as I can't see
// a way to point golangs resolver at a specific hosts.
req := new(dns.Msg)
req.Id = dns.Id()
req.RecursionDesired = true
req.Question = make([]dns.Question, 1)
req.Question[0] = dns.Question{
Name: hostname,
Qtype: dns.TypeA,
Qclass: dns.ClassINET,
}
c := new(dns.Client)
res, _, err := c.Exchange(req, fmt.Sprintf("127.0.0.1:%d", udpPort))
require.Nil(t, err)
require.True(t, gotRequest)
require.True(t, res.Len() > maxSize)
}

0 comments on commit 67f9749

Please sign in to comment.