Explorar el Código

Make A and AAAA records always work with MaxHosts

Ask Bjørn Hansen hace 7 años
padre
commit
2f5d31c7b8
Se han modificado 3 ficheros con 43 adiciones y 2 borrados
  1. 11 0
      dns/test.example.com.json
  2. 17 0
      zones/picker.go
  3. 15 2
      zones/reader.go

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

@@ -215,6 +215,17 @@
           100
         ]
       ],
+      "aaaa": [
+        {
+          "aaaa": "2a07:2180:0:1::400"
+        },
+        {
+          "aaaa": "2607:f238:3::1:45"
+        },
+        {
+          "aaaa": "2403:300:a0c:f000::1"
+        }
+      ],
       "max_hosts": "1",
       "closest": true
     }

+ 17 - 0
zones/picker.go

@@ -9,6 +9,21 @@ import (
 	"github.com/miekg/dns"
 )
 
+// AlwaysWeighted types always honors 'MaxHosts', even
+// without an explicit weight set. (This list is slightly arbitrary).
+var AlwaysWeighted = []uint16{
+	dns.TypeA, dns.TypeAAAA, dns.TypeCNAME,
+}
+
+var alwaysWeighted map[uint16]struct{}
+
+func init() {
+	alwaysWeighted = map[uint16]struct{}{}
+	for _, t := range AlwaysWeighted {
+		alwaysWeighted[t] = struct{}{}
+	}
+}
+
 func (zone *Zone) filterHealth(servers Records) (Records, int) {
 	// Remove any unhealthy servers
 	tmpServers := servers[:0]
@@ -71,6 +86,8 @@ func (zone *Zone) Picker(label *Label, qtype uint16, max int, location *geo.Loca
 	// this way since the first prototype, it might not make
 	// sense anymore. This probably makes NS records and such
 	// work as expected.
+	// A, AAAA and CNAME records ("AlwaysWeighted") are always given
+	// a weight so MaxHosts works for those even if weight isn't set.
 	if label.Weight[qtype] == 0 {
 		return servers
 	}

+ 15 - 2
zones/reader.go

@@ -490,7 +490,7 @@ func setupZoneData(data map[string]interface{}, zone *Zone) {
 
 	// Loop over exisiting labels, create zone records for missing sub-domains
 	// and set TTLs
-	for k := range zone.Labels {
+	for k, l := range zone.Labels {
 		if strings.Contains(k, ".") {
 			subLabels := strings.Split(k, ".")
 			for i := 1; i < len(subLabels); i++ {
@@ -500,11 +500,24 @@ func setupZoneData(data map[string]interface{}, zone *Zone) {
 				}
 			}
 		}
-		for _, records := range zone.Labels[k].Records {
+
+		for qtype, records := range l.Records {
+
+			setWeight := false
+
+			if _, ok := alwaysWeighted[qtype]; ok && l.Weight[qtype] == 0 {
+				setWeight = true
+			}
+
 			for _, r := range records {
 				// We add the TTL as a last pass because we might not have
 				// processed it yet when we process the record data.
 
+				if setWeight {
+					r.Weight = 1
+					l.Weight[qtype] += r.Weight
+				}
+
 				var defaultTtl uint32 = 86400
 				if r.RR.Header().Rrtype != dns.TypeNS {
 					// NS records have special treatment. If they are not specified, they default to 86400 rather than