package dns import ( "bytes" "fmt" "io" "net/netip" "sort" "time" "darvaza.org/core" "github.com/libdns/libdns" ) // SortAddrSlice sorts a slice of [netip.Addr] func SortAddrSlice(s []netip.Addr) []netip.Addr { sort.Slice(s, func(i, j int) bool { return s[i].Less(s[j]) }) return s } // SortAddrRecords sorts a slice of [AddrRecord] // by Name and Address func SortAddrRecords(s []AddrRecord) []AddrRecord { sort.Slice(s, func(i, j int) bool { return s[i].Name < s[j].Name }) for _, p := range s { SortAddrSlice(p.Addr) } return s } // AddrRecord represents an A or AAAA record type AddrRecord struct { Name string Addr []netip.Addr } // Sort sorts the addresses of the record func (rr *AddrRecord) Sort() { SortAddrSlice(rr.Addr) } // Export converts the record into libdns.Record func (rr *AddrRecord) Export() []libdns.Record { out := make([]libdns.Record, len(rr.Addr)) for i, addr := range rr.Addr { out[i] = libdns.Record{ Name: rr.Name, TTL: time.Second * 1, Type: core.IIf(addr.Is6(), "AAAA", "A"), Value: addr.String(), } } return out } // WriteTo writes the record in BIND notation func (rr *AddrRecord) WriteTo(w io.Writer) (int64, error) { var total int for _, addr := range rr.Addr { n, err := fmt.Fprint(w, rr.Name, "\t", 1, "\t", core.IIf(addr.Is6(), "AAAA", "A"), "\t", addr.String(), "\n") switch { case err != nil: return 0, err case n > 0: total += n } } return int64(total), nil } // String converts the record into BIND entries func (rr *AddrRecord) String() string { var buf bytes.Buffer _, _ = rr.WriteTo(&buf) return buf.String() }