|
|
|
@ -6,6 +6,7 @@ import (
|
|
|
|
|
"io" |
|
|
|
|
"net/netip" |
|
|
|
|
"sort" |
|
|
|
|
"strings" |
|
|
|
|
"time" |
|
|
|
|
|
|
|
|
|
"darvaza.org/core" |
|
|
|
@ -38,6 +39,53 @@ func SortAddrRecords(s []AddrRecord) []AddrRecord {
|
|
|
|
|
return s |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// SortRecords sorts a slice of [libdns.Record], by Name, Type and Value
|
|
|
|
|
func SortRecords(s []libdns.Record) []libdns.Record { |
|
|
|
|
sort.Slice(s, func(i, j int) bool { |
|
|
|
|
return lessRecord(s[i], s[j]) |
|
|
|
|
}) |
|
|
|
|
return s |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func lessRecord(a, b libdns.Record) bool { |
|
|
|
|
aName := strings.ToLower(a.Name) |
|
|
|
|
bName := strings.ToLower(b.Name) |
|
|
|
|
|
|
|
|
|
switch { |
|
|
|
|
case aName < bName: |
|
|
|
|
return true |
|
|
|
|
case aName > bName: |
|
|
|
|
return false |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
aType := strings.ToUpper(a.Type) |
|
|
|
|
bType := strings.ToUpper(b.Type) |
|
|
|
|
|
|
|
|
|
switch { |
|
|
|
|
case aType < bType: |
|
|
|
|
return true |
|
|
|
|
case aType > bType: |
|
|
|
|
return false |
|
|
|
|
case aType == "A", aType == "AAAA": |
|
|
|
|
// IP Addresses
|
|
|
|
|
var aa, ba netip.Addr |
|
|
|
|
|
|
|
|
|
switch { |
|
|
|
|
case aa.UnmarshalText([]byte(a.Value)) != nil: |
|
|
|
|
// bad address on a
|
|
|
|
|
return true |
|
|
|
|
case ba.UnmarshalText([]byte(b.Value)) != nil: |
|
|
|
|
// bad address on b
|
|
|
|
|
return false |
|
|
|
|
default: |
|
|
|
|
return aa.Less(ba) |
|
|
|
|
} |
|
|
|
|
default: |
|
|
|
|
// text
|
|
|
|
|
return a.Value < b.Value |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// SortRegions sorts regions. first by length those 3-character
|
|
|
|
|
// or shorter, and then by length. It's mostly aimed at
|
|
|
|
|
// supporting ISO-3166 order
|
|
|
|
|