2012-07-15 06:01:52 +10:00
|
|
|
package dns
|
|
|
|
|
|
|
|
// A structure for handling zone data
|
|
|
|
|
|
|
|
import (
|
2012-07-16 21:31:18 +10:00
|
|
|
"radix"
|
2012-07-15 06:01:52 +10:00
|
|
|
)
|
|
|
|
|
2012-07-16 07:15:04 +10:00
|
|
|
// Zone represents a DNS zone.
|
2012-07-15 06:01:52 +10:00
|
|
|
type Zone struct {
|
2012-07-17 03:46:16 +10:00
|
|
|
Origin string // Origin of the zone
|
2012-07-16 02:11:17 +10:00
|
|
|
*radix.Radix // Zone data
|
2012-07-15 06:01:52 +10:00
|
|
|
}
|
|
|
|
|
2012-07-17 05:16:42 +10:00
|
|
|
// ZoneData holds all the RRs having their ownername equal to Name.
|
2012-07-15 06:01:52 +10:00
|
|
|
type ZoneData struct {
|
2012-07-17 03:09:50 +10:00
|
|
|
Name string // Domain name for this node
|
|
|
|
RR map[uint16][]RR // Map of the RR type to the RR
|
|
|
|
// DNSSEC signatures for the RRsets
|
|
|
|
Signatures []*RR_RRSIG
|
2012-07-17 05:20:58 +10:00
|
|
|
// Always false, except for glue... TODO(mg)
|
|
|
|
NonAuth bool
|
2012-07-15 06:54:49 +10:00
|
|
|
}
|
|
|
|
|
2012-07-17 05:16:42 +10:00
|
|
|
// NewZone creates an initialized zone with Origin set origin.
|
2012-07-17 03:09:50 +10:00
|
|
|
func NewZone(origin string) *Zone {
|
2012-07-17 03:46:16 +10:00
|
|
|
if origin == "" {
|
|
|
|
origin = "."
|
|
|
|
}
|
|
|
|
if _, _, ok := IsDomainName(origin); !ok {
|
|
|
|
return nil
|
|
|
|
}
|
2012-07-15 06:54:49 +10:00
|
|
|
z := new(Zone)
|
2012-07-17 03:46:16 +10:00
|
|
|
z.Origin = Fqdn(origin)
|
2012-07-16 02:11:17 +10:00
|
|
|
z.Radix = radix.New()
|
2012-07-15 06:54:49 +10:00
|
|
|
return z
|
|
|
|
}
|
|
|
|
|
2012-07-17 05:16:42 +10:00
|
|
|
// Insert inserts an RR into the zone. Duplicate data overwrites the
|
|
|
|
// old data.
|
|
|
|
func (z *Zone) Insert(r RR) error {
|
2012-07-17 03:46:16 +10:00
|
|
|
if !IsSubDomain(r.Header().Name, z.Origin) {
|
2012-07-17 05:16:42 +10:00
|
|
|
return &Error{Err: "out of zone data", Name: r.Header().Name}
|
2012-07-17 03:46:16 +10:00
|
|
|
}
|
|
|
|
|
2012-07-16 02:11:17 +10:00
|
|
|
zd := z.Radix.Find(r.Header().Name)
|
|
|
|
if zd == nil {
|
|
|
|
zd := new(ZoneData)
|
|
|
|
zd.Name = r.Header().Name
|
2012-07-16 03:16:39 +10:00
|
|
|
zd.RR = make(map[uint16][]RR)
|
|
|
|
zd.Signatures = make([]*RR_RRSIG, 0)
|
2012-07-16 02:11:17 +10:00
|
|
|
switch t := r.Header().Rrtype; t {
|
|
|
|
case TypeRRSIG:
|
|
|
|
zd.Signatures = append(zd.Signatures, r.(*RR_RRSIG))
|
2012-07-17 05:20:58 +10:00
|
|
|
case TypeNS:
|
|
|
|
// NS records with other names than z.Origin are non-auth
|
2012-07-17 05:24:05 +10:00
|
|
|
if r.Header().Name != z.Origin {
|
2012-07-17 05:20:58 +10:00
|
|
|
zd.NonAuth = true
|
|
|
|
}
|
|
|
|
fallthrough
|
2012-07-16 02:11:17 +10:00
|
|
|
default:
|
|
|
|
zd.RR[t] = append(zd.RR[t], r)
|
|
|
|
}
|
2012-07-16 02:16:20 +10:00
|
|
|
z.Radix.Insert(r.Header().Name, zd)
|
2012-07-17 05:24:05 +10:00
|
|
|
return nil
|
2012-07-16 02:11:17 +10:00
|
|
|
}
|
2012-07-17 05:24:05 +10:00
|
|
|
// Name already there
|
2012-07-16 02:11:17 +10:00
|
|
|
switch t := r.Header().Rrtype; t {
|
|
|
|
case TypeRRSIG:
|
2012-07-16 21:31:18 +10:00
|
|
|
zd.Value.(*ZoneData).Signatures = append(zd.Value.(*ZoneData).Signatures, r.(*RR_RRSIG))
|
2012-07-17 05:20:58 +10:00
|
|
|
case TypeNS:
|
2012-07-17 05:24:05 +10:00
|
|
|
if r.Header().Name != z.Origin {
|
|
|
|
zd.Value.(*ZoneData).NonAuth = true
|
2012-07-17 05:20:58 +10:00
|
|
|
}
|
|
|
|
fallthrough
|
2012-07-16 02:11:17 +10:00
|
|
|
default:
|
2012-07-16 21:31:18 +10:00
|
|
|
zd.Value.(*ZoneData).RR[t] = append(zd.Value.(*ZoneData).RR[t], r)
|
2012-07-16 02:11:17 +10:00
|
|
|
}
|
2012-07-17 05:24:05 +10:00
|
|
|
return nil
|
2012-07-15 06:54:49 +10:00
|
|
|
}
|
|
|
|
|
2012-07-17 05:24:05 +10:00
|
|
|
func (z *Zone) Remove(r RR) error {
|
|
|
|
return nil
|
2012-07-15 06:01:52 +10:00
|
|
|
}
|