diff --git a/CHANGELOG.md b/CHANGELOG.md index 40ab4e97..5739fdd3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,9 @@ +* DNS + * Modified `ParseRData` method to remove priority, weight and port from targets **only** when those values are same for all `SRV` targets. + Otherwise, targets are returned untouched and `priority`, `weight` and `port` in the map are not populated. @@ -78,7 +81,6 @@ - ## 8.0.0 (March 19, 2024) diff --git a/pkg/dns/record_lookup.go b/pkg/dns/record_lookup.go index fdc15cee..2d52288a 100644 --- a/pkg/dns/record_lookup.go +++ b/pkg/dns/record_lookup.go @@ -387,15 +387,39 @@ func resolveRRSIGType(rData []string, fieldMap map[string]interface{}) { } func resolveSRVType(rData, newRData []string, fieldMap map[string]interface{}) { - // pull out some fields - parts := strings.Split(rData[0], " ") - fieldMap["priority"], _ = strconv.Atoi(parts[0]) - fieldMap["weight"], _ = strconv.Atoi(parts[1]) - fieldMap["port"], _ = strconv.Atoi(parts[2]) - // populate target + // if all targets have the same priority, weight and port, process it in the old way + priorityMap := make(map[int]struct{}) + weightMap := make(map[int]struct{}) + portMap := make(map[int]struct{}) for _, rContent := range rData { - parts = strings.Split(rContent, " ") - newRData = append(newRData, parts[3]) + parts := strings.Split(rContent, " ") + priority, _ := strconv.Atoi(parts[0]) + weight, _ := strconv.Atoi(parts[1]) + port, _ := strconv.Atoi(parts[2]) + priorityMap[priority] = struct{}{} + weightMap[weight] = struct{}{} + portMap[port] = struct{}{} + } + // all values are the same, so process in the old way + if len(priorityMap) == 1 && len(weightMap) == 1 && len(portMap) == 1 { + // pull out some fields + parts := strings.Split(rData[0], " ") + fieldMap["priority"], _ = strconv.Atoi(parts[0]) + fieldMap["weight"], _ = strconv.Atoi(parts[1]) + fieldMap["port"], _ = strconv.Atoi(parts[2]) + // populate target + for _, rContent := range rData { + parts = strings.Split(rContent, " ") + newRData = append(newRData, parts[3]) + } + } else { + delete(fieldMap, "priority") + delete(fieldMap, "weight") + delete(fieldMap, "port") + // populate target + for _, rContent := range rData { + newRData = append(newRData, rContent) + } } fieldMap["target"] = newRData } diff --git a/pkg/dns/record_lookup_test.go b/pkg/dns/record_lookup_test.go index 8d939b58..ac81c8a3 100644 --- a/pkg/dns/record_lookup_test.go +++ b/pkg/dns/record_lookup_test.go @@ -318,10 +318,12 @@ func TestDNS_ParseRData(t *testing.T) { client := Client(session.Must(session.New())) tests := map[string]struct { + rType string rdata []string expect map[string]interface{} }{ "AFSDB": { + rType: "AFSDB", rdata: []string{"1 bar.com"}, expect: map[string]interface{}{ "subtype": 1, @@ -329,6 +331,7 @@ func TestDNS_ParseRData(t *testing.T) { }, }, "SVCB": { + rType: "SVCB", rdata: []string{"0 svc4.example.com."}, expect: map[string]interface{}{ "target": []string{}, @@ -337,6 +340,7 @@ func TestDNS_ParseRData(t *testing.T) { }, }, "HTTPS": { + rType: "HTTPS", rdata: []string{"3 https.example.com. alpn=bar port=8080"}, expect: map[string]interface{}{ "target": []string{}, @@ -345,11 +349,28 @@ func TestDNS_ParseRData(t *testing.T) { "svc_params": "alpn=bar port=8080", }, }, + "SRV with default values": { + rType: "SRV", + rdata: []string{"10 60 5060 big.example.com.", "10 60 5060 small.example.com."}, + expect: map[string]interface{}{ + "port": 5060, + "priority": 10, + "weight": 60, + "target": []string{"big.example.com.", "small.example.com."}, + }, + }, + "SRV without default values": { + rType: "SRV", + rdata: []string{"10 60 5060 big.example.com.", "20 50 5060 small.example.com."}, + expect: map[string]interface{}{ + "target": []string{"10 60 5060 big.example.com.", "20 50 5060 small.example.com."}, + }, + }, } for name, test := range tests { t.Run(name, func(t *testing.T) { - out := client.ParseRData(context.Background(), name, test.rdata) + out := client.ParseRData(context.Background(), test.rType, test.rdata) assert.Equal(t, test.expect, out) })