types.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. package main
  2. import (
  3. "github.com/miekg/dns"
  4. )
  5. type Options struct {
  6. Serial int
  7. Ttl int
  8. }
  9. type Record struct {
  10. RR dns.RR
  11. Weight int
  12. }
  13. type Records []Record
  14. func (s Records) Len() int { return len(s) }
  15. func (s Records) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
  16. type RecordsByWeight struct{ Records }
  17. func (s RecordsByWeight) Less(i, j int) bool { return s.Records[i].Weight > s.Records[j].Weight }
  18. type Label struct {
  19. Label string
  20. MaxHosts int
  21. Ttl int
  22. Records map[uint16]Records
  23. Weight map[uint16]int
  24. }
  25. type labels map[string]*Label
  26. type Zones map[string]*Zone
  27. type Zone struct {
  28. Origin string
  29. Labels labels
  30. LenLabels int
  31. Options Options
  32. }
  33. func (l *Label) firstRR(dnsType uint16) dns.RR {
  34. return l.Records[dnsType][0].RR
  35. }
  36. func (z *Zone) SoaRR() dns.RR {
  37. return z.Labels[""].firstRR(dns.TypeSOA)
  38. }
  39. func (z *Zone) findLabels(s, cc string, qtype uint16) *Label {
  40. if qtype == dns.TypeANY {
  41. // short-circuit mostly to avoid subtle bugs later
  42. return z.Labels[s]
  43. }
  44. selectors := []string{}
  45. if len(cc) > 0 {
  46. if len(s) > 0 {
  47. cc = s + "." + cc
  48. }
  49. selectors = append(selectors, cc)
  50. }
  51. // TODO(ask) Add continent, see https://github.com/abh/geodns/issues/1
  52. selectors = append(selectors, s)
  53. for _, name := range selectors {
  54. if label, ok := z.Labels[name]; ok {
  55. // return the label if it has the right records
  56. // TODO(ask) Should this also look for CNAME or aliases?
  57. if label.Records[qtype] != nil {
  58. return label
  59. }
  60. }
  61. }
  62. return z.Labels[s]
  63. }