From 5f642d390c8c51fc808533a0ad90b73b0bb03fb6 Mon Sep 17 00:00:00 2001 From: Michael Bridgen Date: Mon, 12 Jan 2015 17:12:15 +0000 Subject: [PATCH] Pass queries for non-local names on to the configured nameserver --- nameserver/server.go | 37 ++++++++++++++++++++++--------------- nameserver/server_test.go | 9 ++++++--- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/nameserver/server.go b/nameserver/server.go index f202f3bb..989e3663 100644 --- a/nameserver/server.go +++ b/nameserver/server.go @@ -72,28 +72,35 @@ func rdnsHandler(lookups []Lookup) dns.HandlerFunc { } } -/* When we receive a request for a name outside of our '.weave' domain, call - the underlying lookup mechanism and return the answer(s) it gives. - Unfortunately, this means that TTLs from a real DNS server are lost - FIXME. +/* When we receive a request for a name outside of our '.weave.local.' + domain, ask the configured DNS server as a fallback. */ func notUsHandler() dns.HandlerFunc { + config, err := dns.ClientConfigFromFile("/etc/resolv.conf") + checkFatal(err) return func(w dns.ResponseWriter, r *dns.Msg) { q := r.Question[0] Debug.Printf("[dns msgid %d] Non-local query: %+v", r.MsgHdr.Id, q) - var responseMsg *dns.Msg - if q.Qtype == dns.TypeA || q.Qtype == dns.TypeAAAA { - if addrs, err := net.LookupIP(q.Name); err == nil { - responseMsg = makeAddressReply(r, &q, addrs) - } else { - responseMsg = makeDNSFailResponse(r) - Debug.Printf("[dns msgid %d] Failed fallback: %s", r.MsgHdr.Id, err) + for _, server := range config.Servers { + reply, err := dns.Exchange(r, fmt.Sprintf("%s:%s", server, config.Port)) + if err != nil { + Debug.Printf("[dns msgid %d] Network error trying %s (%s)", + r.MsgHdr.Id, server, err) + continue } - } else { - Warning.Printf("[dns msgid %d] Non-local query not handled: %+v", - r.MsgHdr.Id, q) - responseMsg = makeDNSFailResponse(r) + if reply != nil && reply.Rcode != dns.RcodeSuccess { + Debug.Printf("[dns msgid %d] Failure reported by %s for query %s", + r.MsgHdr.Id, server, q.Name) + continue + } + Debug.Printf("[dns msgid %d] Given answer by %s for query %s", + r.MsgHdr.Id, server, q.Name) + w.WriteMsg(reply) + return } - w.WriteMsg(responseMsg) + Warning.Printf("[dns msgid %d] Failed lookup for external name %s", + r.MsgHdr.Id, q.Name) + w.WriteMsg(makeDNSFailResponse(r)) } } diff --git a/nameserver/server_test.go b/nameserver/server_test.go index c0050179..8ad62f06 100644 --- a/nameserver/server_test.go +++ b/nameserver/server_test.go @@ -68,12 +68,15 @@ func TestDNSServer(t *testing.T) { wt.AssertStatus(t, r.Rcode, dns.RcodeNameError, "DNS response code") wt.AssertEqualInt(t, len(r.Answer), 0, "Number of answers") - // This non-local query should fail because we don't handle MX records + // This non-local query for an MX record should succeed by being + // passed on to the configured (/etc/resolv.conf) DNS server. m.SetQuestion(nonLocalName, dns.TypeMX) r, _, err = c.Exchange(m, dnsAddr) wt.AssertNoErr(t, err) - wt.AssertStatus(t, r.Rcode, dns.RcodeNameError, "DNS response code") - wt.AssertEqualInt(t, len(r.Answer), 0, "Number of answers") + wt.AssertStatus(t, r.Rcode, dns.RcodeSuccess, "DNS response code") + if !(len(r.Answer) > 0) { + t.Fatal("Number of answers > 0") + } // Not testing MDNS functionality of server here (yet) }