Add nsec3 search functions

This commit is contained in:
Miek Gieben 2011-07-29 20:06:52 +02:00
parent e6fb6095c4
commit 7e644793fe
1 changed files with 65 additions and 36 deletions

101
zone.go
View File

@ -6,7 +6,7 @@ package dns
import ( import (
"os" "os"
"strings" "strings"
) )
const _CLASS = 2 << 16 const _CLASS = 2 << 16
@ -53,15 +53,15 @@ func (z Zone) PopRR() RR {
if s == nil { if s == nil {
return nil return nil
} }
switch { switch {
case len(s.RRs) != 0: case len(s.RRs) != 0:
return s.RRs.Pop() return s.RRs.Pop()
case len(s.RRsigs) != 0: case len(s.RRsigs) != 0:
return s.RRsigs.Pop() return s.RRsigs.Pop()
case s.Nxt != nil: case s.Nxt != nil:
return s.Nxt return s.Nxt
} }
panic("not reached") panic("not reached")
return nil return nil
} }
@ -70,9 +70,9 @@ func (z Zone) Len() int {
for _, im := range z { for _, im := range z {
for _, s := range im { for _, s := range im {
i += len(s.RRs) + len(s.RRsigs) i += len(s.RRs) + len(s.RRsigs)
if s.Nxt != nil { if s.Nxt != nil {
i++ i++
} }
} }
} }
return i return i
@ -84,9 +84,9 @@ func (z Zone) String() string {
for _, s1 := range im { for _, s1 := range im {
s += s1.RRs.String() s += s1.RRs.String()
s += s1.RRsigs.String() s += s1.RRsigs.String()
if s1.Nxt != nil { if s1.Nxt != nil {
s += s1.Nxt.String() + "\n" s += s1.Nxt.String() + "\n"
} }
} }
} }
return s return s
@ -112,20 +112,20 @@ func (z Zone) PushRR(r RR) {
// Push a new ZRRset to the zone // Push a new ZRRset to the zone
func (z Zone) Push(s *ZRRset) { func (z Zone) Push(s *ZRRset) {
// s can hold RRs, RRsigs or a Nxt // s can hold RRs, RRsigs or a Nxt
name := "" name := ""
i := 0 i := 0
switch { switch {
case len(s.RRs) != 0: case len(s.RRs) != 0:
name = s.RRs[0].Header().Name name = s.RRs[0].Header().Name
i = intval(s.RRs[0].Header().Class, s.RRs[0].Header().Rrtype) i = intval(s.RRs[0].Header().Class, s.RRs[0].Header().Rrtype)
case len(s.RRsigs) != 0: case len(s.RRsigs) != 0:
name = s.RRsigs[0].Header().Name name = s.RRsigs[0].Header().Name
i = intval(s.RRsigs[0].Header().Class, s.RRsigs[0].(*RR_RRSIG).TypeCovered) i = intval(s.RRsigs[0].Header().Class, s.RRsigs[0].(*RR_RRSIG).TypeCovered)
case s.Nxt != nil: case s.Nxt != nil:
name = s.Nxt.Header().Name name = s.Nxt.Header().Name
i = intval(s.Nxt.Header().Class, s.Nxt.Header().Rrtype) i = intval(s.Nxt.Header().Class, s.Nxt.Header().Rrtype)
} }
if z[name] == nil { if z[name] == nil {
im := make(map[int]*ZRRset) // intmap im := make(map[int]*ZRRset) // intmap
im[i] = s im[i] = s
@ -143,15 +143,15 @@ func (z Zone) Push(s *ZRRset) {
// Return NXDomain, Name error, wildcard? // Return NXDomain, Name error, wildcard?
// Casing! // Casing!
func (z Zone) LookupRR(r RR) (*ZRRset, os.Error) { func (z Zone) LookupRR(r RR) (*ZRRset, os.Error) {
if r.Header().Rrtype == TypeRRSIG { if r.Header().Rrtype == TypeRRSIG {
return z.LookupName(r.Header().Name, r.Header().Class, r.(*RR_RRSIG).TypeCovered) return z.LookupName(r.Header().Name, r.Header().Class, r.(*RR_RRSIG).TypeCovered)
} }
return z.LookupName(r.Header().Name, r.Header().Class, r.Header().Rrtype) return z.LookupName(r.Header().Name, r.Header().Class, r.Header().Rrtype)
} }
func (z Zone) LookupQuestion(q Question) (*ZRRset, os.Error) { func (z Zone) LookupQuestion(q Question) (*ZRRset, os.Error) {
// Impossible to look for an typecovered in a question, because the rdata is // Impossible to look for an typecovered in a question, because the rdata is
// not there. // not there.
return z.LookupName(q.Name, q.Qclass, q.Qtype) return z.LookupName(q.Name, q.Qclass, q.Qtype)
} }
@ -162,7 +162,7 @@ func (z Zone) LookupName(qname string, qclass, qtype uint16) (*ZRRset, os.Error)
if s, ok := im[i]; ok { if s, ok := im[i]; ok {
return s, nil return s, nil
} }
// Wildcard 'n stuff // Wildcard 'n stuff
return nil, ErrName return nil, ErrName
} }
return nil, nil return nil, nil
@ -172,3 +172,32 @@ func (z Zone) LookupName(qname string, qclass, qtype uint16) (*ZRRset, os.Error)
func intval(c, t uint16) int { func intval(c, t uint16) int {
return int(c)*_CLASS + int(t) return int(c)*_CLASS + int(t)
} }
// Needed for NSEC/NSEC3 in DNSSEC
// SortInsert insert the string s in the already sorted
// vector p. If s is already present it is not inserted again.
func SortInsert(p *vector.StringVector, s string) {
sa := sort.StringArray(*p)
i := sa.Search(s)
if i < p.Len() && p.At(i) == s {
// element already there
return
}
p.Insert(i, s)
}
// Search searches the sorted vector p using binary search. If
// the element s can not be found, the previous element is returned.
func SortSearch(p *vector.StringVector, s string) string {
sa := sort.StringArray(*p)
i := sa.Search(s)
// with zones there must always be one before
if p.At(i) == s {
return s
}
if i > 0 {
i--
}
return p.At(i)
}