ソースを参照

Don't return NXDOMAIN for A queries to _status and _country

Closes #37
Ask Bjørn Hansen 12 年 前
コミット
d8728ce5d8
2 ファイル変更43 行追加16 行削除
  1. 26 16
      serve.go
  2. 17 0
      serve_test.go

+ 26 - 16
serve.go

@@ -104,25 +104,35 @@ func serve(w dns.ResponseWriter, req *dns.Msg, z *Zone) {
 
 	if labels == nil {
 
-		if label == "_status" && (qtype == dns.TypeANY || qtype == dns.TypeTXT) {
-			m.Answer = statusRR(z)
+		firstLabel := (strings.Split(label, "."))[0]
+
+		if firstLabel == "_status" {
+			if qtype == dns.TypeANY || qtype == dns.TypeTXT {
+				m.Answer = statusRR(label + "." + z.Origin + ".")
+			} else {
+				m.Ns = append(m.Ns, z.SoaRR())
+			}
 			m.Authoritative = true
 			w.WriteMsg(m)
 			return
 		}
 
-		if label == "_country" && (qtype == dns.TypeANY || qtype == dns.TypeTXT) {
-			h := dns.RR_Header{Ttl: 1, Class: dns.ClassINET, Rrtype: dns.TypeTXT}
-			h.Name = "_country." + z.Origin + "."
-
-			m.Answer = []dns.RR{&dns.TXT{Hdr: h,
-				Txt: []string{
-					w.RemoteAddr().String(),
-					ip,
-					string(country),
-					string(countries.CountryContinent[country]),
-				},
-			}}
+		if firstLabel == "_country" {
+			if qtype == dns.TypeANY || qtype == dns.TypeTXT {
+				h := dns.RR_Header{Ttl: 1, Class: dns.ClassINET, Rrtype: dns.TypeTXT}
+				h.Name = label + "." + z.Origin + "."
+
+				m.Answer = []dns.RR{&dns.TXT{Hdr: h,
+					Txt: []string{
+						w.RemoteAddr().String(),
+						ip,
+						string(country),
+						string(countries.CountryContinent[country]),
+					},
+				}}
+			} else {
+				m.Ns = append(m.Ns, z.SoaRR())
+			}
 
 			m.Authoritative = true
 			w.WriteMsg(m)
@@ -164,9 +174,9 @@ func serve(w dns.ResponseWriter, req *dns.Msg, z *Zone) {
 	return
 }
 
-func statusRR(z *Zone) []dns.RR {
+func statusRR(label string) []dns.RR {
 	h := dns.RR_Header{Ttl: 1, Class: dns.ClassINET, Rrtype: dns.TypeTXT}
-	h.Name = "_status." + z.Origin + "."
+	h.Name = label
 
 	status := map[string]string{"v": VERSION, "id": serverId}
 

+ 17 - 0
serve_test.go

@@ -39,6 +39,23 @@ func (s *ServeSuite) TestServing(c *C) {
 		c.Fail()
 	}
 
+	// Allow _country and _status queries as long as the first label is that
+	r = exchange(c, "_country.foo.pgeodns.", dns.TypeTXT)
+	txt = r.Answer[0].(*dns.TXT).Txt[0]
+	// Got appropriate response for _country txt query
+	if !strings.HasPrefix(txt, "127.0.0.1:") {
+		c.Log("Unexpected result for _country.foo.pgeodns", txt)
+		c.Fail()
+	}
+
+	// Make sure A requests for _status doesn't NXDOMAIN
+	r = exchange(c, "_status.pgeodns.", dns.TypeA)
+	c.Check(r.Answer, HasLen, 0)
+	// Got one SOA record
+	c.Check(r.Ns, HasLen, 1)
+	// NOERROR for A request
+	c.Check(r.Rcode, Equals, dns.RcodeSuccess)
+
 	r = exchange(c, "bar.test.example.com.", dns.TypeA)
 	ip := r.Answer[0].(*dns.A).A
 	c.Check(ip.String(), Equals, "192.168.1.2")