You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
1.6 KiB
90 lines
1.6 KiB
1 year ago
|
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()
|
||
|
}
|