Преглед изворни кода

Support weighted cname responses

Ask Bjørn Hansen пре 11 година
родитељ
комит
ad2ba945c8
3 измењених фајлова са 54 додато и 16 уклоњено
  1. 3 0
      dns/test.example.com.json
  2. 16 0
      serve_test.go
  3. 35 16
      zones.go

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

@@ -51,6 +51,9 @@
     "www.europe": {
       "cname": "geo-europe.bitnames.com."
     },
+    "www.se": {
+      "cname": [ [ "geo-europe", 10 ], [ "geo-dk", 10 ] ]
+    },
     "www-cname": {
       "cname": "bar"
     },

+ 16 - 0
serve_test.go

@@ -103,6 +103,22 @@ func (s *ServeSuite) TestServingMixedCase(c *C) {
 
 }
 
+func (s *ServeSuite) TestCname(c *C) {
+	// Cname, two possible results
+
+	results := make(map[string]int)
+
+	for i := 0; i < 10; i++ {
+		r := exchange(c, "www.se.test.example.com.", dns.TypeA)
+		target := r.Answer[0].(*dns.CNAME).Target
+		results[target]++
+	}
+
+	// Two possible results from this cname
+	c.Check(results, HasLen, 2)
+
+}
+
 func (s *ServeSuite) TestServingAliases(c *C) {
 	// Alias, no geo matches
 	r := exchange(c, "bar-alias.test.example.com.", dns.TypeA)

+ 35 - 16
zones.go

@@ -300,21 +300,11 @@ func setupZoneData(data map[string]interface{}, Zone *Zone) {
 
 				switch dnsType {
 				case dns.TypeA, dns.TypeAAAA:
-					rec := records[rType][i].([]interface{})
-					ip := rec[0].(string)
-					var err error
-
-					if len(rec) > 1 {
-						switch rec[1].(type) {
-						case string:
-							record.Weight, err = strconv.Atoi(rec[1].(string))
-							if err != nil {
-								panic("Error converting weight to integer")
-							}
-						case float64:
-							record.Weight = int(rec[1].(float64))
-						}
-					}
+
+					str, weight := getStringWeight(records[rType][i].([]interface{}))
+					ip := str
+					record.Weight = weight
+
 					switch dnsType {
 					case dns.TypeA:
 						if x := net.ParseIP(ip); x != nil {
@@ -350,10 +340,18 @@ func setupZoneData(data map[string]interface{}, Zone *Zone) {
 
 				case dns.TypeCNAME:
 					rec := records[rType][i]
-					target := rec.(string)
+					var target string
+					var weight int
+					switch rec.(type) {
+					case string:
+						target = rec.(string)
+					case []interface{}:
+						target, weight = getStringWeight(rec.([]interface{}))
+					}
 					if !dns.IsFqdn(target) {
 						target = target + "." + Zone.Origin
 					}
+					record.Weight = weight
 					record.RR = &dns.CNAME{Hdr: h, Target: dns.Fqdn(target)}
 
 				case dns.TypeMF:
@@ -465,6 +463,27 @@ func setupZoneData(data map[string]interface{}, Zone *Zone) {
 	//log.Println(Zones[k])
 }
 
+func getStringWeight(rec []interface{}) (string, int) {
+
+	str := rec[0].(string)
+	var weight int
+	var err error
+
+	if len(rec) > 1 {
+		switch rec[1].(type) {
+		case string:
+			weight, err = strconv.Atoi(rec[1].(string))
+			if err != nil {
+				panic("Error converting weight to integer")
+			}
+		case float64:
+			weight = int(rec[1].(float64))
+		}
+	}
+
+	return str, weight
+}
+
 func setupSOA(Zone *Zone) {
 	label := Zone.Labels[""]