Remove node locks

This commit is contained in:
Miek Gieben 2013-05-06 11:07:22 +02:00
parent 77bba78ef3
commit 2a79dc91a7
1 changed files with 9 additions and 25 deletions

34
zone.go
View File

@ -11,6 +11,8 @@ import (
"time" "time"
) )
// TODO(mg): NSEC3
// Zone represents a DNS zone. It's safe for concurrent use by // Zone represents a DNS zone. It's safe for concurrent use by
// multilpe goroutines. // multilpe goroutines.
type Zone struct { type Zone struct {
@ -97,7 +99,6 @@ type ZoneData struct {
RR map[uint16][]RR // Map of the RR type to the RR RR map[uint16][]RR // Map of the RR type to the RR
Signatures map[uint16][]*RRSIG // DNSSEC signatures for the RRs, stored under type covered Signatures map[uint16][]*RRSIG // DNSSEC signatures for the RRs, stored under type covered
NonAuth bool // Always false, except for NSsets that differ from z.Origin NonAuth bool // Always false, except for NSsets that differ from z.Origin
*sync.RWMutex
} }
// NewZoneData creates a new zone data element. // NewZoneData creates a new zone data element.
@ -105,7 +106,6 @@ func NewZoneData() *ZoneData {
zd := new(ZoneData) zd := new(ZoneData)
zd.RR = make(map[uint16][]RR) zd.RR = make(map[uint16][]RR)
zd.Signatures = make(map[uint16][]*RRSIG) zd.Signatures = make(map[uint16][]*RRSIG)
zd.RWMutex = new(sync.RWMutex)
return zd return zd
} }
@ -158,15 +158,14 @@ Types:
// Insert inserts the RR r into the zone. // Insert inserts the RR r into the zone.
func (z *Zone) Insert(r RR) error { func (z *Zone) Insert(r RR) error {
z.Lock()
defer z.Unlock()
if !z.isSubDomain(r.Header().Name) { if !z.isSubDomain(r.Header().Name) {
return &Error{Err: "out of zone data", Name: r.Header().Name} return &Error{Err: "out of zone data", Name: r.Header().Name}
} }
z.Lock()
z.ModTime = time.Now().UTC() z.ModTime = time.Now().UTC()
zd, ok := z.Names[r.Header().Name] zd, ok := z.Names[r.Header().Name]
if !ok { if !ok {
defer z.Unlock()
// Check if it's a wildcard name // Check if it's a wildcard name
if len(r.Header().Name) > 1 && r.Header().Name[0] == '*' && r.Header().Name[1] == '.' { if len(r.Header().Name) > 1 && r.Header().Name[0] == '*' && r.Header().Name[1] == '.' {
z.Wildcard++ z.Wildcard++
@ -192,9 +191,6 @@ func (z *Zone) Insert(r RR) error {
z.sortedNames[i] = r.Header().Name z.sortedNames[i] = r.Header().Name
return nil return nil
} }
z.Unlock()
zd.Lock()
defer zd.Unlock()
// Name already there // Name already there
switch t := r.Header().Rrtype; t { switch t := r.Header().Rrtype; t {
case TypeRRSIG: case TypeRRSIG:
@ -215,15 +211,12 @@ func (z *Zone) Insert(r RR) error {
// this is a no-op. // this is a no-op.
func (z *Zone) Remove(r RR) error { func (z *Zone) Remove(r RR) error {
z.Lock() z.Lock()
defer z.Unlock()
zd, ok := z.Names[r.Header().Name] zd, ok := z.Names[r.Header().Name]
if !ok { if !ok {
defer z.Unlock()
return nil return nil
} }
z.ModTime = time.Now().UTC() z.ModTime = time.Now().UTC()
z.Unlock()
zd.Lock()
defer zd.Unlock()
switch t := r.Header().Rrtype; t { switch t := r.Header().Rrtype; t {
case TypeRRSIG: case TypeRRSIG:
sigtype := r.(*RRSIG).TypeCovered sigtype := r.(*RRSIG).TypeCovered
@ -268,19 +261,17 @@ func (z *Zone) Remove(r RR) error {
// method is when processing a RemoveName dynamic update packet. // method is when processing a RemoveName dynamic update packet.
func (z *Zone) RemoveName(s string) error { func (z *Zone) RemoveName(s string) error {
z.Lock() z.Lock()
defer z.Unlock()
_, ok := z.Names[s] _, ok := z.Names[s]
if !ok { if !ok {
defer z.Unlock()
return nil return nil
} }
z.ModTime = time.Now().UTC() z.ModTime = time.Now().UTC()
defer z.Unlock()
delete(z.Names, s) delete(z.Names, s)
i := sort.SearchStrings(z.sortedNames, s) i := sort.SearchStrings(z.sortedNames, s)
copy(z.sortedNames[i:], z.sortedNames[i+1:]) copy(z.sortedNames[i:], z.sortedNames[i+1:])
z.sortedNames[len(z.sortedNames)-1] = "" z.sortedNames[len(z.sortedNames)-1] = ""
z.sortedNames = z.sortedNames[:len(z.sortedNames)-1] z.sortedNames = z.sortedNames[:len(z.sortedNames)-1]
if len(s) > 1 && s[0] == '*' && s[1] == '.' { if len(s) > 1 && s[0] == '*' && s[1] == '.' {
z.Wildcard-- z.Wildcard--
if z.Wildcard < 0 { if z.Wildcard < 0 {
@ -294,15 +285,12 @@ func (z *Zone) RemoveName(s string) error {
// Typical use of this method is when processing a RemoveRRset dynamic update packet. // Typical use of this method is when processing a RemoveRRset dynamic update packet.
func (z *Zone) RemoveRRset(s string, t uint16) error { func (z *Zone) RemoveRRset(s string, t uint16) error {
z.Lock() z.Lock()
defer z.Unlock()
zd, ok := z.Names[s] zd, ok := z.Names[s]
if !ok { if !ok {
defer z.Unlock()
return nil return nil
} }
z.ModTime = time.Now().UTC() z.ModTime = time.Now().UTC()
z.Unlock()
zd.Lock()
defer zd.Unlock()
switch t { switch t {
case TypeRRSIG: case TypeRRSIG:
// empty all signature maps // empty all signature maps
@ -457,16 +445,12 @@ func signerRoutine(z *Zone, wg *sync.WaitGroup, keys map[*DNSKEY]PrivateKey, key
} }
} }
// Sign signs a single ZoneData node. The zonedata itself is locked for writing, // Sign signs a single ZoneData node.
// during the execution. It is important that the nodes' next record does not // The caller must take care that the zone itself is also locked for writing.
// change. The caller must take care that the zone itself is also locked for writing.
// For a more complete description see zone.Sign. // For a more complete description see zone.Sign.
// Note, because this method has no (direct) // Note, because this method has no (direct)
// access to the zone's SOA record, the SOA's Minttl value should be set in *config. // access to the zone's SOA record, the SOA's Minttl value should be set in *config.
func (node *ZoneData) Sign(next string, keys map[*DNSKEY]PrivateKey, keytags map[*DNSKEY]uint16, config *SignatureConfig) error { func (node *ZoneData) Sign(next string, keys map[*DNSKEY]PrivateKey, keytags map[*DNSKEY]uint16, config *SignatureConfig) error {
node.Lock()
defer node.Unlock()
n, nsecok := node.RR[TypeNSEC] n, nsecok := node.RR[TypeNSEC]
bitmap := []uint16{TypeNSEC, TypeRRSIG} bitmap := []uint16{TypeNSEC, TypeRRSIG}
bitmapEqual := true bitmapEqual := true