Browse Source

Merge branch 'master' into edns-subnet

Ask Bjørn Hansen 13 years ago
parent
commit
3d7499c9e2
10 changed files with 86 additions and 25 deletions
  1. 8 0
      CHANGES.md
  2. 5 0
      README.md
  3. 16 9
      config.go
  4. 21 3
      config_test.go
  5. 7 0
      dns/test.example.com.json
  6. 1 1
      geodns.go
  7. 3 3
      serve.go
  8. 19 4
      serve_test.go
  9. 2 1
      types.go
  10. 4 4
      zone_test.go

+ 8 - 0
CHANGES.md

@@ -0,0 +1,8 @@
+# GeoDNS Changelog
+
+## 2.2.0
+
+- The CNAME configuration changed so the name of the current zone is appended
+to the target name if the target is not a fqdn (ends with a "."). This is a rare
+change not compatible with existing data. To upgrade make all cname's fqdn's until
+all servers are running v2.2.0 or newer.

+ 5 - 0
README.md

@@ -102,6 +102,11 @@ Same format as A records (except the record type is "aaaa").
 
 ### CNAME
 
+The target will have the current zone name appended if it's not a FQDN (since v2.2.0).
+
+  { "cname": "target.example.com." }
+  { "cname": "www" }
+
 ### NS
 
 ### MX

+ 16 - 9
config.go

@@ -97,6 +97,7 @@ func readZoneFile(zoneName, fileName string) (*Zone, error) {
 	Zone.LenLabels = dns.LenLabels(Zone.Origin)
 	Zone.Options.Ttl = 120
 	Zone.Options.MaxHosts = 2
+	Zone.Options.Contact = "support.bitnames.com"
 
 	if err == nil {
 		var objmap map[string]interface{}
@@ -113,12 +114,14 @@ func readZoneFile(zoneName, fileName string) (*Zone, error) {
 			//log.Printf("k: %s v: %#v, T: %T\n", k, v, v)
 
 			switch k {
-			case "ttl", "serial", "max_hosts":
+			case "ttl", "serial", "max_hosts", "contact":
 				switch option := k; option {
 				case "ttl":
 					Zone.Options.Ttl = valueToInt(v)
 				case "serial":
 					Zone.Options.Serial = valueToInt(v)
+				case "contact":
+					Zone.Options.Contact = v.(string)
 				case "max_hosts":
 					Zone.Options.MaxHosts = valueToInt(v)
 				}
@@ -244,13 +247,13 @@ func setupZoneData(data map[string]interface{}, Zone *Zone) {
 					switch dnsType {
 					case dns.TypeA:
 						if x := net.ParseIP(ip); x != nil {
-							record.RR = &dns.RR_A{Hdr: h, A: x}
+							record.RR = &dns.A{Hdr: h, A: x}
 							break
 						}
 						panic("Bad A record")
 					case dns.TypeAAAA:
 						if x := net.ParseIP(ip); x != nil {
-							record.RR = &dns.RR_AAAA{Hdr: h, AAAA: x}
+							record.RR = &dns.AAAA{Hdr: h, AAAA: x}
 							break
 						}
 						panic("Bad AAAA record")
@@ -269,19 +272,23 @@ func setupZoneData(data map[string]interface{}, Zone *Zone) {
 					if rec["preference"] != nil {
 						pref = uint16(valueToInt(rec["preference"]))
 					}
-					record.RR = &dns.RR_MX{
+					record.RR = &dns.MX{
 						Hdr:        h,
 						Mx:         mx,
 						Preference: pref}
 
 				case dns.TypeCNAME:
 					rec := records[rType][i]
-					record.RR = &dns.RR_CNAME{Hdr: h, Target: dns.Fqdn(rec.(string))}
+					target := rec.(string)
+					if !dns.IsFqdn(target) {
+						target = target + "." + Zone.Origin
+					}
+					record.RR = &dns.CNAME{Hdr: h, Target: dns.Fqdn(target)}
 
 				case dns.TypeMF:
 					rec := records[rType][i]
 					// MF records (how we store aliases) are not FQDNs
-					record.RR = &dns.RR_MF{Hdr: h, Mf: rec.(string)}
+					record.RR = &dns.MF{Hdr: h, Mf: rec.(string)}
 
 				case dns.TypeNS:
 					rec := records[rType][i]
@@ -305,7 +312,7 @@ func setupZoneData(data map[string]interface{}, Zone *Zone) {
 						panic("Unrecognized NS format/syntax")
 					}
 
-					rr := &dns.RR_NS{Hdr: h, Ns: dns.Fqdn(ns)}
+					rr := &dns.NS{Hdr: h, Ns: dns.Fqdn(ns)}
 
 					record.RR = rr
 
@@ -338,11 +345,11 @@ func setupSOA(Zone *Zone) {
 	primaryNs := "ns"
 
 	if record, ok := label.Records[dns.TypeNS]; ok {
-		primaryNs = record[0].RR.(*dns.RR_NS).Ns
+		primaryNs = record[0].RR.(*dns.NS).Ns
 	}
 
 	s := Zone.Origin + ". 3600 IN SOA " +
-		primaryNs + " support.bitnames.com. " +
+		primaryNs + " " + Zone.Options.Contact + " " +
 		strconv.Itoa(Zone.Options.Serial) +
 		" 5400 5400 2419200 " +
 		strconv.Itoa(Zone.Options.Ttl)

+ 21 - 3
config_test.go

@@ -1,6 +1,7 @@
 package main
 
 import (
+	"github.com/miekg/dns"
 	. "launchpad.net/gocheck"
 	"testing"
 )
@@ -21,9 +22,26 @@ func (s *ConfigSuite) TestReadConfigs(c *C) {
 	// Just check that example.com loaded, too.
 	c.Check(s.zones["example.com"].Origin, Equals, "example.com")
 
+	tz := s.zones["test.example.com"]
+
 	// The real tests are in test.example.com so we have a place
 	// to make nutty configuration entries
-	c.Check(s.zones["test.example.com"].Origin, Equals, "test.example.com")
-	c.Check(s.zones["test.example.com"].Options.MaxHosts, Equals, 2)
-	c.Check(s.zones["test.example.com"].Labels["weight"].MaxHosts, Equals, 1)
+	c.Check(tz.Origin, Equals, "test.example.com")
+	c.Check(tz.Options.MaxHosts, Equals, 2)
+	c.Check(tz.Options.Contact, Equals, "support.bitnames.com")
+	c.Check(tz.Labels["weight"].MaxHosts, Equals, 1)
+
+	/* test different cname targets */
+	c.Check(tz.Labels["www"].
+		firstRR(dns.TypeCNAME).(*dns.CNAME).
+		Target, Equals, "geo.bitnames.com.")
+
+	c.Check(tz.Labels["www-cname"].
+		firstRR(dns.TypeCNAME).(*dns.CNAME).
+		Target, Equals, "bar.test.example.com.")
+
+	c.Check(tz.Labels["www-alias"].
+		firstRR(dns.TypeCNAME).(*dns.CNAME).
+		Target, Equals, "bar-alias.test.example.com.")
+
 }

+ 7 - 0
dns/test.example.com.json

@@ -1,6 +1,7 @@
 { "serial": 3,
   "ttl":    600,
   "max_hosts": 2,
+  "contact": "support.bitnames.com",
   "data" : {
     "":  {
       "ns": { "ns1.example.net.": null, "ns2.example.net.": null },
@@ -37,6 +38,12 @@
     "www": {
       "cname": "geo.bitnames.com."
     },
+    "www-cname": {
+      "cname": "bar"
+    },
+    "www-alias": {
+      "cname": "bar-alias"
+    },
     "cname-long-ttl": {
       "cname": "geo.bitnames.com.",
       "ttl": 86400

+ 1 - 1
geodns.go

@@ -11,7 +11,7 @@ import (
 	"time"
 )
 
-var VERSION string = "2.1.2"
+var VERSION string = "2.2.0"
 var gitVersion string
 var serverId string
 

+ 3 - 3
serve.go

@@ -85,7 +85,7 @@ func serve(w dns.ResponseWriter, req *dns.Msg, z *Zone) {
 	if alias := z.findLabels(label, "", dns.TypeMF); alias != nil &&
 		alias.Records[dns.TypeMF] != nil {
 		// We found an alias record, so pretend the question was for that name instead
-		label = alias.firstRR(dns.TypeMF).(*dns.RR_MF).Mf
+		label = alias.firstRR(dns.TypeMF).(*dns.MF).Mf
 	}
 
 	labels := z.findLabels(label, country, qtype)
@@ -102,7 +102,7 @@ func serve(w dns.ResponseWriter, req *dns.Msg, z *Zone) {
 			h := dns.RR_Header{Ttl: 1, Class: dns.ClassINET, Rrtype: dns.TypeTXT}
 			h.Name = "_country." + z.Origin + "."
 
-			m.Answer = []dns.RR{&dns.RR_TXT{Hdr: h,
+			m.Answer = []dns.RR{&dns.TXT{Hdr: h,
 				Txt: []string{
 					w.RemoteAddr().String(),
 					ip,
@@ -175,7 +175,7 @@ func statusRR(z *Zone) []dns.RR {
 
 	js, err := json.Marshal(status)
 
-	return []dns.RR{&dns.RR_TXT{Hdr: h, Txt: []string{string(js)}}}
+	return []dns.RR{&dns.TXT{Hdr: h, Txt: []string{string(js)}}}
 }
 
 func setupServerFunc(Zone *Zone) func(dns.ResponseWriter, *dns.Msg) {

+ 19 - 4
serve_test.go

@@ -17,25 +17,40 @@ func (s *ConfigSuite) TestServing(c *C) {
 	time.Sleep(100 * time.Millisecond)
 
 	r := exchange(c, "_status.pgeodns.", dns.TypeTXT)
-	txt := r.Answer[0].(*dns.RR_TXT).Txt[0]
+	txt := r.Answer[0].(*dns.TXT).Txt[0]
 	if !strings.HasPrefix(txt, "{") {
 		c.Log("Unexpected result for _status.pgeodns", txt)
 		c.Fail()
 	}
 
 	r = exchange(c, "bar.test.example.com.", dns.TypeA)
-	ip := r.Answer[0].(*dns.RR_A).A
+	ip := r.Answer[0].(*dns.A).A
 	c.Check(ip.String(), Equals, "192.168.1.2")
 
 	r = exchange(c, "test.example.com.", dns.TypeSOA)
-	soa := r.Answer[0].(*dns.RR_SOA)
+	soa := r.Answer[0].(*dns.SOA)
 	serial := soa.Serial
 	c.Check(int(serial), Equals, 3)
 
 	// no AAAA records for 'bar', so check we get a soa record back
 	r = exchange(c, "test.example.com.", dns.TypeAAAA)
-	soa2 := r.Ns[0].(*dns.RR_SOA)
+	soa2 := r.Ns[0].(*dns.SOA)
 	c.Check(soa, DeepEquals, soa2)
+
+	/* CNAMEs */
+	r = exchange(c, "www.test.example.com.", dns.TypeA)
+	c.Check(r.Answer[0].(*dns.CNAME).Target, Equals, "geo.bitnames.com.")
+
+	// TODO: make the alias and cname respond with the data for the target, too?
+	r = exchange(c, "www-alias.test.example.com.", dns.TypeA)
+	c.Check(r.Answer[0].(*dns.CNAME).Target, Equals, "bar-alias.test.example.com.")
+
+	/* MX */
+	r = exchange(c, "test.example.com.", dns.TypeMX)
+	c.Check(r.Answer[0].(*dns.MX).Mx, Equals, "mx.example.net.")
+	c.Check(r.Answer[1].(*dns.MX).Mx, Equals, "mx2.example.net.")
+	c.Check(r.Answer[1].(*dns.MX).Preference, Equals, uint16(20))
+
 }
 
 func exchange(c *C, name string, dnstype uint16) *dns.Msg {

+ 2 - 1
types.go

@@ -9,6 +9,7 @@ type Options struct {
 	Serial   int
 	Ttl      int
 	MaxHosts int
+	Contact  string
 }
 
 type Record struct {
@@ -80,7 +81,7 @@ func (z *Zone) findLabels(s, cc string, qtype uint16) *Label {
 
 			// look for aliases
 			if label.Records[dns.TypeMF] != nil {
-				name = label.firstRR(dns.TypeMF).(*dns.RR_MF).Mf
+				name = label.firstRR(dns.TypeMF).(*dns.MF).Mf
 				// BUG(ask) - restructure this so it supports chains of aliases
 				label, ok = z.Labels[name]
 				if label == nil {

+ 4 - 4
zone_test.go

@@ -12,16 +12,16 @@ func (s *ConfigSuite) TestZone(c *C) {
 	// Make sure that the empty "no.bar" zone gets skipped and "bar" is used
 	label := ex.findLabels("bar", "no", dns.TypeA)
 	c.Check(label.Records[dns.TypeA], HasLen, 1)
-	c.Check(label.Records[dns.TypeA][0].RR.(*dns.RR_A).A.String(), Equals, "192.168.1.2")
+	c.Check(label.Records[dns.TypeA][0].RR.(*dns.A).A.String(), Equals, "192.168.1.2")
 
 	label = ex.findLabels("", "", dns.TypeMX)
 	Mxs := label.Records[dns.TypeMX]
 	c.Check(Mxs, HasLen, 2)
-	c.Check(Mxs[0].RR.(*dns.RR_MX).Mx, Equals, "mx.example.net.")
-	c.Check(Mxs[1].RR.(*dns.RR_MX).Mx, Equals, "mx2.example.net.")
+	c.Check(Mxs[0].RR.(*dns.MX).Mx, Equals, "mx.example.net.")
+	c.Check(Mxs[1].RR.(*dns.MX).Mx, Equals, "mx2.example.net.")
 
 	Mxs = ex.findLabels("", "dk", dns.TypeMX).Records[dns.TypeMX]
 	c.Check(Mxs, HasLen, 1)
-	c.Check(Mxs[0].RR.(*dns.RR_MX).Mx, Equals, "mx-eu.example.net.")
+	c.Check(Mxs[0].RR.(*dns.MX).Mx, Equals, "mx-eu.example.net.")
 
 }