diff --git a/nameserver/addrs.go b/nameserver/addrs.go index 1e315a91..6d6e3abd 100644 --- a/nameserver/addrs.go +++ b/nameserver/addrs.go @@ -32,6 +32,7 @@ type ZoneObservable interface { ObserveInaddr(inaddr string, observer ZoneRecordObserver) error } +type ZoneObserverFunc func(string, ZoneRecordObserver) error type ZoneRecordObserver func() ///////////////////////////////////////////////////////////// diff --git a/nameserver/dns.go b/nameserver/dns.go index 904a9bf2..3b8b8c57 100644 --- a/nameserver/dns.go +++ b/nameserver/dns.go @@ -33,6 +33,8 @@ func makeTruncatedReply(r *dns.Msg) *dns.Msg { return reply } +type DNSResponseBuilder func(r *dns.Msg, q *dns.Question, addrs []ZoneRecord) *dns.Msg + func makeAddressReply(r *dns.Msg, q *dns.Question, addrs []ZoneRecord) *dns.Msg { answers := make([]dns.RR, len(addrs)) header := makeHeader(r, q) diff --git a/nameserver/server.go b/nameserver/server.go index 9c066ea6..f2bc6d99 100644 --- a/nameserver/server.go +++ b/nameserver/server.go @@ -3,36 +3,48 @@ package nameserver import ( "bytes" "fmt" + "github.com/benbjohnson/clock" "github.com/miekg/dns" . "github.com/weaveworks/weave/common" "net" + "strconv" "sync" + "time" ) const ( - DefaultServerPort = 53 // The default server port - DefaultCLICfgFile = "/etc/resolv.conf" // default "resolv.conf" file to try to load - DefaultUDPBuflen = 4096 // bigger than the default 512 - DefaultCacheLen = 8192 // default cache capacity - DefaultResolvWorkers = 8 // default number of resolution workers - DefaultTimeout = 5 // default timeout for DNS resolutions + DefaultServerPort = 53 // The default server port + DefaultCLICfgFile = "/etc/resolv.conf" // default "resolv.conf" file to try to load + DefaultUDPBuflen = 4096 // bigger than the default 512 + DefaultCacheLen = 8192 // default cache capacity + DefaultTimeout = 5 // default timeout for DNS resolutions ) type DNSServerConfig struct { + // The zone + Zone Zone // (Optional) client config file for resolving upstream servers UpstreamCfgFile string // (Optional) DNS client config for the fallback server(s) UpstreamCfg *dns.ClientConfig // (Optional) port number (for TCP and UDP) Port int - // (Optional) local domain (ie, "weave.local.") - LocalDomain string // (Optional) cache size CacheLen int + // (Optional) disable the cache + CacheDisabled bool // (Optional) timeout for DNS queries Timeout int // (Optional) UDP buffer length UDPBufLen int + // (Optional) force a specific cache + Cache ZoneCache + // (Optional) TTL for negative results in the local domain + CacheNegLocalTTL int + // (Optional) for a specific clock provider + Clock clock.Clock + // (Optional) Listening socket read timeout (in milliseconds) + ListenReadTimeout int } type dnsProtocol uint8 @@ -53,51 +65,64 @@ func (proto dnsProtocol) String() string { } // get a new dns.Client for a protocol -func (proto dnsProtocol) GetNewClient(bufsize int) *dns.Client { +func (proto dnsProtocol) GetNewClient(bufsize int, timeout time.Duration) *dns.Client { switch proto { case protTCP: - return &dns.Client{Net: "tcp"} + return &dns.Client{Net: "tcp", ReadTimeout: timeout} case protUDP: - return &dns.Client{Net: "udp", UDPSize: uint16(bufsize)} + return &dns.Client{Net: "udp", ReadTimeout: timeout, UDPSize: uint16(bufsize)} } return nil } +// a DNS server type DNSServer struct { - Zone Zone - Iface *net.Interface - Upstream *dns.ClientConfig - udpSrv *dns.Server - tcpSrv *dns.Server - mdnsCli *MDNSClient - mdnsSrv *MDNSServer - cache *Cache - timeout int - udpBuf int - listenersWg *sync.WaitGroup - + Zone Zone + Upstream *dns.ClientConfig Domain string // the local domain ListenAddr string // the address the server is listening at + + udpSrv *dns.Server + tcpSrv *dns.Server + pc net.PacketConn + lst net.Listener + cache ZoneCache + cacheDisabled bool + negLocalTTL int + timeout time.Duration + readTimeout time.Duration + udpBuf int + listenersWg *sync.WaitGroup + clock clock.Clock } // Creates a new DNS server -func NewDNSServer(config DNSServerConfig, zone Zone, iface *net.Interface) (s *DNSServer, err error) { +func NewDNSServer(config DNSServerConfig) (s *DNSServer, err error) { s = &DNSServer{ - Zone: zone, - Iface: iface, - listenersWg: new(sync.WaitGroup), - + Zone: config.Zone, Domain: DefaultLocalDomain, - ListenAddr: fmt.Sprintf(":%d", DefaultServerPort), + ListenAddr: fmt.Sprintf(":%d", config.Port), + + listenersWg: new(sync.WaitGroup), + timeout: time.Duration(config.Timeout) * time.Millisecond, + readTimeout: time.Duration(config.ListenReadTimeout) * time.Millisecond, + cacheDisabled: false, + negLocalTTL: negLocalTTL, + clock: config.Clock, + } + + // check some basic parameters are valid + if s.Zone == nil { + return nil, fmt.Errorf("No valid Zone provided in server initialization") + } + if len(s.Domain) == 0 { + return nil, fmt.Errorf("No valid Domain provided in server initialization") + } + if s.clock == nil { + s.clock = clock.New() } // fill empty parameters with defaults... - if config.Port != 0 { - s.ListenAddr = fmt.Sprintf(":%d", config.Port) - } - if len(config.LocalDomain) > 0 { - s.Domain = config.LocalDomain - } if config.UpstreamCfg != nil { s.Upstream = config.UpstreamCfg } else { @@ -110,88 +135,97 @@ func NewDNSServer(config DNSServerConfig, zone Zone, iface *net.Interface) (s *D } } if config.Timeout > 0 { - s.timeout = config.Timeout + s.timeout = time.Duration(config.Timeout) * time.Millisecond } if config.UDPBufLen > 0 { s.udpBuf = config.UDPBufLen } - s.mdnsCli, err = NewMDNSClient() - if err != nil { - return + if config.CacheNegLocalTTL > 0 { + s.negLocalTTL = config.CacheNegLocalTTL } - s.mdnsSrv, err = NewMDNSServer(s.Zone, false) - if err != nil { - return + if config.CacheDisabled { + s.cacheDisabled = true } - cacheLen := DefaultCacheLen - if config.CacheLen > 0 { - cacheLen = config.CacheLen + if !s.cacheDisabled { + if config.Cache != nil { + s.cache = config.Cache + } else { + cacheLen := DefaultCacheLen + if config.CacheLen > 0 { + cacheLen = config.CacheLen + } + if s.cache, err = NewCache(cacheLen, s.clock); err != nil { + return + } + } } - Debug.Printf("[dns] Initializing cache: %d entries", config.CacheLen) - s.cache, err = NewCache(cacheLen, nil) - if err != nil { - return - } - - // create two DNS request multiplexerers, depending on the protocol used by clients - // (we use the same protocol for asking upstream servers) - mux := func(proto dnsProtocol) *dns.ServeMux { - m := dns.NewServeMux() - m.HandleFunc(s.Domain, s.queryHandler(proto)) - m.HandleFunc(RDNSDomain, s.rdnsHandler(proto)) - m.HandleFunc(".", s.notUsHandler(proto)) - return m - } - - s.udpSrv = &dns.Server{Addr: s.ListenAddr, Net: "udp", Handler: mux(protUDP)} - s.tcpSrv = &dns.Server{Addr: s.ListenAddr, Net: "tcp", Handler: mux(protTCP)} return } // Start the DNS server func (s *DNSServer) Start() error { - Info.Printf("Using mDNS on %v", s.Iface) - err := s.mdnsCli.Start(s.Iface) - CheckFatal(err) - err = s.mdnsSrv.Start(s.Iface) - CheckFatal(err) + Info.Printf("[dns] Upstream server(s): %+v", s.Upstream) + if s.cacheDisabled { + Info.Printf("[dns] Cache: disabled") + } else { + Info.Printf("[dns] Cache: %d entries", s.cache.Capacity()) + } + + pc, err := net.ListenPacket("udp", s.ListenAddr) + if err != nil { + return err + } + s.pc = pc + + _, port, err := net.SplitHostPort(pc.LocalAddr().String()) + if err != nil { + return err + } + s.ListenAddr = fmt.Sprintf(":%s", port) + s.udpSrv = &dns.Server{PacketConn: s.pc, Handler: s.createMux(protUDP), ReadTimeout: s.readTimeout} + + // Bind the TCP socket at the same port, aborting otherwise + l, err := net.Listen("tcp", s.ListenAddr) + if err != nil { + s.Stop() + return err + } + s.lst = l + s.tcpSrv = &dns.Server{Listener: l, Handler: s.createMux(protTCP), ReadTimeout: s.readTimeout} s.listenersWg.Add(2) go func() { defer s.listenersWg.Done() - Debug.Printf("Listening for DNS on %s (UDP)", s.ListenAddr) - err = s.udpSrv.ListenAndServe() + Info.Printf("[dns] Listening for DNS on %s (UDP)", s.ListenAddr) + err := s.udpSrv.ActivateAndServe() CheckFatal(err) - Debug.Printf("DNS UDP server exiting...") + Debug.Printf("[dns] DNS UDP server exiting...") }() go func() { defer s.listenersWg.Done() - Debug.Printf("Listening for DNS on %s (TCP)", s.ListenAddr) - err = s.tcpSrv.ListenAndServe() + Info.Printf("[dns] Listening for DNS on %s (TCP)", s.ListenAddr) + err := s.tcpSrv.ActivateAndServe() CheckFatal(err) - Debug.Printf("DNS TCP server exiting...") + Debug.Printf("[dns] DNS TCP server exiting...") }() // Waiting for all goroutines to finish (otherwise they die as main routine dies) s.listenersWg.Wait() - Info.Printf("WeaveDNS server exiting...") + Info.Printf("[dns] Server exiting...") return nil } // Return status string func (s *DNSServer) Status() string { var buf bytes.Buffer - fmt.Fprintln(&buf, "Local domain", s.Domain) fmt.Fprintln(&buf, "Listen address", s.ListenAddr) - fmt.Fprintln(&buf, "mDNS interface", s.Iface) fmt.Fprintln(&buf, "Fallback DNS config", s.Upstream) - fmt.Fprintf(&buf, "Zone database:\n%s", s.Zone) return buf.String() } @@ -206,111 +240,110 @@ func (s *DNSServer) Stop() error { } s.listenersWg.Wait() - // shutdown the mDNS server - s.mdnsSrv.Stop() - return nil } -func (s *DNSServer) queryHandler(proto dnsProtocol) dns.HandlerFunc { - zoneLookup := func(lookup ZoneLookup, q *dns.Question, r *dns.Msg) (*dns.Msg, []ZoneRecord, error) { - ips, err := lookup.LookupName(q.Name) - if err != nil { - return nil, nil, err - } - return makeAddressReply(r, q, ips), ips, nil - } - - fallback := func(w dns.ResponseWriter, r *dns.Msg) { +// Create a multiplexer for requests +// We must create two DNS request multiplexers, depending on the protocol used by +// clients (as we use the same protocol for asking upstream servers) +func (s *DNSServer) createMux(proto dnsProtocol) *dns.ServeMux { + failFallback := func(w dns.ResponseWriter, r *dns.Msg) { w.WriteMsg(makeDNSFailResponse(r)) } - - return s.commonQueryHandler(proto, "Query", dns.TypeA, zoneLookup, fallback) -} - -func (s *DNSServer) rdnsHandler(proto dnsProtocol) dns.HandlerFunc { - zoneLookup := func(lookup ZoneLookup, q *dns.Question, r *dns.Msg) (*dns.Msg, []ZoneRecord, error) { - names, err := lookup.LookupInaddr(q.Name) - if err != nil { - return nil, nil, err - } - return makePTRReply(r, q, names), names, nil - } - notUsHandler := s.notUsHandler(proto) - fallback := func(w dns.ResponseWriter, r *dns.Msg) { + notUsFallback := func(w dns.ResponseWriter, r *dns.Msg) { Info.Printf("[dns msgid %d] -> sending to fallback server", r.MsgHdr.Id) notUsHandler(w, r) } - return s.commonQueryHandler(proto, "Reverse query", dns.TypePTR, zoneLookup, fallback) + // create the multiplexer + m := dns.NewServeMux() + m.HandleFunc(s.Zone.Domain(), s.localHandler(proto, "Query", dns.TypeA, + s.Zone.DomainLookupName, makeAddressReply, s.Zone.ObserveName, failFallback)) + m.HandleFunc(RDNSDomain, s.localHandler(proto, "Reverse query", dns.TypePTR, + s.Zone.DomainLookupInaddr, makePTRReply, s.Zone.ObserveInaddr, notUsFallback)) + m.HandleFunc(".", s.notUsHandler(proto)) + return m } -func (s *DNSServer) commonQueryHandler(proto dnsProtocol, kind string, qtype uint16, - zoneLookup func(ZoneLookup, *dns.Question, *dns.Msg) (*dns.Msg, []ZoneRecord, error), fallback dns.HandlerFunc) dns.HandlerFunc { +// Process a request for a name/address in the '.weave.local.' zone +func (s *DNSServer) localHandler(proto dnsProtocol, kind string, qtype uint16, + lookup func(inaddr string) ([]ZoneRecord, error), + msgBuilder DNSResponseBuilder, observer ZoneObserverFunc, fallback dns.HandlerFunc) dns.HandlerFunc { return func(w dns.ResponseWriter, r *dns.Msg) { q := r.Question[0] Debug.Printf("[dns msgid %d] %s: %+v", r.MsgHdr.Id, kind, q) maxLen := getMaxReplyLen(r, proto) - lookups := []ZoneLookup{s.Zone, s.mdnsCli} - reply, err := s.cache.Get(r, maxLen) - if err != nil { - if err == errNoLocalReplies { - Debug.Printf("[dns msgid %d] Cached 'no local replies' - skipping local lookup", r.MsgHdr.Id) - lookups = []ZoneLookup{s.Zone} - } else { - Debug.Printf("[dns msgid %d] Error from cache: %s", r.MsgHdr.Id, err) - w.WriteMsg(makeDNSFailResponse(r)) - return + // cache a reponse if the cache is enabled, and observe the name/IP + maybeCache := func(m *dns.Msg, ttl int, flags uint8) { + if !s.cacheDisabled { + s.cache.Put(r, m, ttl, flags) + // any change in the Zone database for this IP/name will lead to this + // cache entry being removed... + // TODO: this closure results in unnecessary `Remove`s and some wasted + // mem... but we can live with that. + observer(q.Name, func() { s.cache.Remove(&q) }) } } - if reply != nil { - Debug.Printf("[dns msgid %d] Returning reply from cache: %s/%d answers", - r.MsgHdr.Id, dns.RcodeToString[reply.MsgHdr.Rcode], len(reply.Answer)) - w.WriteMsg(reply) - return + + if !s.cacheDisabled { + reply, err := s.cache.Get(r, maxLen) + if err != nil { + if err == errNoLocalReplies { + Debug.Printf("[dns msgid %d] Cached no-local-replies", r.MsgHdr.Id) + fallback(w, r) + return + } else { + Debug.Printf("[dns msgid %d] Error from cache: %s", r.MsgHdr.Id, err) + w.WriteMsg(makeDNSFailResponse(r)) + return + } + } + if reply != nil { + Debug.Printf("[dns msgid %d] Returning reply from cache: %s/%d answers", + r.MsgHdr.Id, dns.RcodeToString[reply.MsgHdr.Rcode], len(reply.Answer)) + w.WriteMsg(reply) + return + } } // catch unsupported queries if q.Qtype != qtype { Debug.Printf("[dns msgid %d] Unsupported query type %s", r.MsgHdr.Id, dns.TypeToString[q.Qtype]) m := makeDNSFailResponse(r) - s.cache.Put(r, m, negLocalTTL, 0) + maybeCache(m, s.negLocalTTL, 0) w.WriteMsg(m) return } - for _, lookup := range lookups { - if m, answers, err := zoneLookup(lookup, &q, r); err == nil { - m.Authoritative = true - Debug.Printf("[dns msgid %d] Caching response for type %s query for '%s': %s [code:%s]", - m.MsgHdr.Id, dns.TypeToString[q.Qtype], q.Name, answers, dns.RcodeToString[m.Rcode]) - s.cache.Put(r, m, nullTTL, 0) - w.WriteMsg(m) - return - } + if answers, err := lookup(q.Name); err != nil { + Info.Printf("[dns msgid %d] No results for type %s query for '%s' [caching no-local]", + r.MsgHdr.Id, dns.TypeToString[q.Qtype], q.Name) + maybeCache(nil, s.negLocalTTL, CacheNoLocalReplies) + fallback(w, r) + } else { + m := msgBuilder(r, &q, answers) + m.Authoritative = true + Debug.Printf("[dns msgid %d] Sending response: %s/%s:%s [code:%s]", + m.MsgHdr.Id, dns.TypeToString[q.Qtype], q.Name, answers, dns.RcodeToString[m.Rcode]) + maybeCache(m, nullTTL, 0) + w.WriteMsg(m) } - - Info.Printf("[dns msgid %d] No results for type %s query for '%s' [caching no-local]", - r.MsgHdr.Id, dns.TypeToString[q.Qtype], q.Name) - s.cache.Put(r, nil, negLocalTTL, CacheNoLocalReplies) - - fallback(w, r) } } // When we receive a request for a name outside of our '.weave.local.' // domain, ask the configured DNS server as a fallback. func (s *DNSServer) notUsHandler(proto dnsProtocol) dns.HandlerFunc { - dnsClient := proto.GetNewClient(DefaultUDPBuflen) + dnsClient := proto.GetNewClient(DefaultUDPBuflen, s.timeout) return func(w dns.ResponseWriter, r *dns.Msg) { - maxLen := getMaxReplyLen(r, proto) q := r.Question[0] - // create a request where we announce our max payload size + // announce our max payload size as the max payload our client supports + maxLen := getMaxReplyLen(r, proto) rcopy := r rcopy.SetEdns0(uint16(maxLen), false) @@ -336,3 +369,12 @@ func (s *DNSServer) notUsHandler(proto dnsProtocol) dns.HandlerFunc { w.WriteMsg(makeDNSFailResponse(r)) } } + +// Get the listen port +func (s *DNSServer) GetPort() (int, error) { + _, portS, err := net.SplitHostPort(s.ListenAddr) + if err != nil { + return 0, err + } + return strconv.Atoi(portS) +} diff --git a/nameserver/server_test.go b/nameserver/server_test.go index 33ff6cb0..8f1897d1 100644 --- a/nameserver/server_test.go +++ b/nameserver/server_test.go @@ -18,10 +18,6 @@ const ( testUDPBufSize = 16384 ) -var ( - testPort = 17625 -) - func setupForTest(t *testing.T) { // fail early if we cannot find a default multicast interface multicast, err := LinkLocalMulticastListener(nil) @@ -29,18 +25,17 @@ func setupForTest(t *testing.T) { t.Fatalf("Unable to create multicast listener: %s. No default multicast interface?", err) } multicast.Close() - - testPort++ } func TestUDPDNSServer(t *testing.T) { setupForTest(t) + const ( - containerID = "foobar" successTestName = "test1.weave.local." - failTestName = "test2.weave.local." + failTestName = "fail.weave.local." nonLocalName = "weave.works." testAddr1 = "10.2.2.1" + containerID = "somecontainer" ) testCIDR1 := testAddr1 + "/24" @@ -80,15 +75,17 @@ func TestUDPDNSServer(t *testing.T) { } // Run another DNS server for fallback - s, fallbackAddr, err := runLocalUDPServer("127.0.0.1:0", fallbackHandler) + fallback, err := newMockedFallback(fallbackHandler, nil) wt.AssertNoErr(t, err) - defer s.Shutdown() + fallback.Start() + defer fallback.Stop() - _, fallbackPort, err := net.SplitHostPort(fallbackAddr) - wt.AssertNoErr(t, err) - - config := &dns.ClientConfig{Servers: []string{"127.0.0.1"}, Port: fallbackPort} - srv, err := NewDNSServer(DNSServerConfig{UpstreamCfg: config, Port: testPort}, zone, nil) + srv, err := NewDNSServer(DNSServerConfig{ + Zone: zone, + UpstreamCfg: fallback.CliConfig, + CacheDisabled: true, + ListenReadTimeout: testSocketTimeout, + }) wt.AssertNoErr(t, err) defer srv.Stop() go srv.Start() @@ -96,6 +93,10 @@ func TestUDPDNSServer(t *testing.T) { var r *dns.Msg + testPort, err := srv.GetPort() + wt.AssertNoErr(t, err) + wt.AssertNotEqualInt(t, testPort, 0, "invalid listen port") + _, r = assertExchange(t, successTestName, dns.TypeA, testPort, 1, 1, 0) wt.AssertType(t, r.Answer[0], (*dns.A)(nil), "DNS record") wt.AssertEqualString(t, r.Answer[0].(*dns.A).A.String(), testAddr1, "IP address") @@ -126,11 +127,11 @@ func TestUDPDNSServer(t *testing.T) { func TestTCPDNSServer(t *testing.T) { setupForTest(t) + const ( numAnswers = 512 nonLocalName = "weave.works." ) - dnsAddr := fmt.Sprintf("localhost:%d", testPort) InitDefaultLogging(testing.Verbose()) Info.Println("TestTCPDNSServer starting") @@ -140,13 +141,14 @@ func TestTCPDNSServer(t *testing.T) { err = zone.Start() wt.AssertNoErr(t, err) defer zone.Stop() - + // generate a list of `numAnswers` IP addresses var addrs []ZoneRecord bs := make([]byte, 4) for i := 0; i < numAnswers; i++ { binary.LittleEndian.PutUint32(bs, uint32(i)) - addrs = append(addrs, Record{"", net.IPv4(bs[0], bs[1], bs[2], bs[3]), 0, 0, 0}) + ip := net.IPv4(bs[0], bs[1], bs[2], bs[3]) + addrs = append(addrs, ZoneRecord(Record{"", ip, 0, 0, 0})) } // handler for the fallback server: it will just return a very long response @@ -173,27 +175,28 @@ func TestTCPDNSServer(t *testing.T) { } t.Logf("Running a DNS fallback server with UDP") - us, fallbackUDPAddr, err := runLocalUDPServer("127.0.0.1:0", fallbackUDPHandler) + fallback, err := newMockedFallback(fallbackUDPHandler, fallbackTCPHandler) wt.AssertNoErr(t, err) - defer us.Shutdown() + fallback.Start() + defer fallback.Stop() - _, fallbackPort, err := net.SplitHostPort(fallbackUDPAddr) - wt.AssertNoErr(t, err) - - t.Logf("Starting another fallback server, with TCP, on the same port as the UDP server") - fallbackTCPAddr := fmt.Sprintf("127.0.0.1:%s", fallbackPort) - ts, fallbackTCPAddr, err := runLocalTCPServer(fallbackTCPAddr, fallbackTCPHandler) - wt.AssertNoErr(t, err) - defer ts.Shutdown() - - t.Logf("Creating a WeaveDNS server instance, falling back to 127.0.0.1:%s", fallbackPort) - config := &dns.ClientConfig{Servers: []string{"127.0.0.1"}, Port: fallbackPort} - srv, err := NewDNSServer(DNSServerConfig{UpstreamCfg: config, Port: testPort}, zone, nil) + t.Logf("Creating a WeaveDNS server instance, falling back to 127.0.0.1:%s", fallback.Port) + srv, err := NewDNSServer(DNSServerConfig{ + Zone: zone, + UpstreamCfg: fallback.CliConfig, + CacheDisabled: true, + ListenReadTimeout: testSocketTimeout, + }) wt.AssertNoErr(t, err) defer srv.Stop() go srv.Start() time.Sleep(100 * time.Millisecond) // Allow sever goroutine to start + testPort, err := srv.GetPort() + wt.AssertNoErr(t, err) + wt.AssertNotEqualInt(t, testPort, 0, "listen port") + dnsAddr := fmt.Sprintf("127.0.0.1:%d", testPort) + t.Logf("Creating a UDP and a TCP client") uc := new(dns.Client) uc.UDPSize = minUDPSize @@ -205,8 +208,8 @@ func TestTCPDNSServer(t *testing.T) { m.RecursionDesired = true m.SetQuestion(nonLocalName, dns.TypeA) - t.Logf("Checking the fallback server at %s returns a truncated response with UDP", fallbackUDPAddr) - r, _, err := uc.Exchange(m, fallbackUDPAddr) + t.Logf("Checking the fallback server at %s returns a truncated response with UDP", fallback.Addr) + r, _, err := uc.Exchange(m, fallback.Addr) t.Logf("Got response from fallback server (UDP) with %d answers", len(r.Answer)) t.Logf("Response:\n%+v\n", r) wt.AssertNoErr(t, err) diff --git a/weavedns/main.go b/weavedns/main.go index 840a7a09..46d0acf2 100644 --- a/weavedns/main.go +++ b/weavedns/main.go @@ -96,13 +96,15 @@ func main() { } srvConfig := weavedns.DNSServerConfig{ - Port: dnsPort, - CacheLen: cacheLen, - Timeout: timeout, - UDPBufLen: udpbuf, + Zone: zone, + Port: dnsPort, + CacheLen: cacheLen, + Timeout: timeout, + UDPBufLen: udpbuf, + CacheDisabled: cacheDisabled, } - srv, err := weavedns.NewDNSServer(srvConfig, zone, iface) + srv, err := weavedns.NewDNSServer(srvConfig) if err != nil { Error.Fatal("[main] Failed to initialize the WeaveDNS server", err) }