dns/zone.go

84 lines
1.9 KiB
Go
Raw Normal View History

2012-07-14 20:01:52 +00:00
package dns
// A structure for handling zone data
import (
"radix"
2012-07-14 20:01:52 +00:00
)
2012-07-15 21:15:04 +00:00
// Zone represents a DNS zone.
2012-07-14 20:01:52 +00:00
type Zone struct {
2012-07-16 17:46:16 +00:00
Origin string // Origin of the zone
2012-07-15 16:11:17 +00:00
*radix.Radix // Zone data
2012-07-14 20:01:52 +00:00
}
2012-07-16 19:16:42 +00:00
// ZoneData holds all the RRs having their ownername equal to Name.
2012-07-14 20:01:52 +00:00
type ZoneData struct {
2012-07-16 17:09:50 +00: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
// Almost always true, except for non-origin NS records (and accompanying glue)
Authoritatve bool
2012-07-14 20:54:49 +00:00
}
2012-07-16 19:16:42 +00:00
// NewZone creates an initialized zone with Origin set origin.
2012-07-16 17:09:50 +00:00
func NewZone(origin string) *Zone {
2012-07-16 17:46:16 +00:00
if origin == "" {
origin = "."
}
if _, _, ok := IsDomainName(origin); !ok {
return nil
}
2012-07-14 20:54:49 +00:00
z := new(Zone)
2012-07-16 17:46:16 +00:00
z.Origin = Fqdn(origin)
2012-07-15 16:11:17 +00:00
z.Radix = radix.New()
2012-07-14 20:54:49 +00:00
return z
}
2012-07-16 19:16:42 +00:00
// Insert inserts an RR into the zone. Duplicate data overwrites the
// old data.
func (z *Zone) Insert(r RR) error {
2012-07-16 17:46:16 +00:00
if !IsSubDomain(r.Header().Name, z.Origin) {
2012-07-16 19:16:42 +00:00
return &Error{Err: "out of zone data", Name: r.Header().Name}
2012-07-16 17:46:16 +00:00
}
2012-07-15 16:11:17 +00:00
zd := z.Radix.Find(r.Header().Name)
if zd == nil {
zd := new(ZoneData)
zd.Name = r.Header().Name
2012-07-15 17:16:39 +00:00
zd.RR = make(map[uint16][]RR)
zd.Signatures = make([]*RR_RRSIG, 0)
2012-07-15 16:11:17 +00:00
switch t := r.Header().Rrtype; t {
case TypeRRSIG:
zd.Signatures = append(zd.Signatures, r.(*RR_RRSIG))
default:
zd.RR[t] = append(zd.RR[t], r)
glueCheck(r)
2012-07-15 16:11:17 +00:00
}
2012-07-15 16:16:20 +00:00
z.Radix.Insert(r.Header().Name, zd)
2012-07-15 16:11:17 +00:00
return
}
2012-07-16 17:46:16 +00:00
// Name already added
2012-07-15 16:11:17 +00:00
switch t := r.Header().Rrtype; t {
case TypeRRSIG:
zd.Value.(*ZoneData).Signatures = append(zd.Value.(*ZoneData).Signatures, r.(*RR_RRSIG))
2012-07-15 16:11:17 +00:00
default:
zd.Value.(*ZoneData).RR[t] = append(zd.Value.(*ZoneData).RR[t], r)
2012-07-15 16:11:17 +00:00
}
return
2012-07-14 20:54:49 +00:00
}
func glueCheck(r RR) {
if n, ok := r.(*RR_NS); ok {
// Check if glue would be needed
if CompareLabels(r.Header().Name, n.Ns) == LenLabels(r.Header().Name) {
println("glue needed?", r.Header().Name, n.Ns)
}
}
}
2012-07-14 20:54:49 +00:00
func (z *Zone) Remove(r RR) {
2012-07-14 20:01:52 +00:00
}