Add much more complex zone structure

A zone is stored in a
map[string]map[int]*ZRRset

where string is the qname and int (in the second map) is
qclass * <large number> + qtype, thereby making it unique.

ZRRset holds:
    RRs     RRset
    RRsigs  RRset
    Nsec    RR
    Nsec3   RR
    Glue    bool

Which holds the RRset for the zone contents. This is grouped
together for DNSSEC purposes, but also helps in non-DNSSEC zones.
(There is of course a increase in memory usage).
This commit is contained in:
Miek Gieben 2011-07-28 22:47:55 +02:00
parent 51d347a0d5
commit caa1502c1e
7 changed files with 262 additions and 135 deletions

60
dns.go
View File

@ -79,16 +79,60 @@ type RR interface {
// An RRset is a slice of RRs. // An RRset is a slice of RRs.
type RRset []RR type RRset []RR
func (r RRset) Len() int { return len(r) } func NewRRset() RRset {
func (r RRset) Less(i, j int) bool { return r[i].Header().Name < r[j].Header().Name } s := make([]RR, 0)
func (r RRset) Swap(i, j int) { r[i], r[j] = r[j], r[i] } return s
}
func (s RRset) Len() int { return len(s) }
func (s RRset) Less(i, j int) bool { return s[i].Header().Name < s[j].Header().Name }
func (s RRset) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s RRset) String() string {
str := ""
for _, r := range s {
str += r.String()
}
return str
}
// Remove the last pushed RR from the RRset. Return nil
// when there is nothing to remove
func (s *RRset) Pop() RR {
if len(*s) == 0 {
return nil
}
// Pop and remove the entry
r := (*s)[len(*s)-1]
*s = (*s)[:len(*s)-1]
return r
}
// Push the RR r to the RRset
func (s *RRset) Push(r RR) bool {
if s.Len() == 0 {
*s = append(*s, r)
return true
}
if (*s)[0].Header().Ttl != r.Header().Ttl {
return false
}
if (*s)[0].Header().Name != r.Header().Name {
return false
}
if (*s)[0].Header().Class != r.Header().Class {
return false
}
*s = append(*s, r)
return true
}
// Check if the RRset is RFC 2181 compliant. // Check if the RRset is RFC 2181 compliant.
func (r RRset) Ok() bool { func (s RRset) Ok() bool {
ttl := r[0].Header().Ttl ttl := s[0].Header().Ttl
name := r[0].Header().Name name := s[0].Header().Name
class := r[0].Header().Class class := s[0].Header().Class
for _, rr := range r[1:] { for _, rr := range s[1:] {
if rr.Header().Ttl != ttl { if rr.Header().Ttl != ttl {
return false return false
} }

View File

@ -27,6 +27,7 @@ a.miek.nl. 345600 IN RRSIG AAAA 8 3 345600 20110823011301 2011072401130
a.miek.nl. 86400 IN NSEC c.miek.nl. A AAAA RRSIG NSEC a.miek.nl. 86400 IN NSEC c.miek.nl. A AAAA RRSIG NSEC
a.miek.nl. 86400 IN RRSIG NSEC 8 3 86400 20110823011301 20110724011301 12051 miek.nl. Rd5HPNllWy/Un6llOKgsgBniFLUb/7KZla544NFwuLtLIO2rdFDBHrMz BeAWLoSXAjhWzU/ICpx9+a4nNNWj9gR8Z9+6RP0qw6ABx2O1L5ZB5fY6 g/hJAumzO3qOKNhF1N71JebLmZVYOYRwhXjql1UB7YKtxKUqVu3K65tm 3l0= a.miek.nl. 86400 IN RRSIG NSEC 8 3 86400 20110823011301 20110724011301 12051 miek.nl. Rd5HPNllWy/Un6llOKgsgBniFLUb/7KZla544NFwuLtLIO2rdFDBHrMz BeAWLoSXAjhWzU/ICpx9+a4nNNWj9gR8Z9+6RP0qw6ABx2O1L5ZB5fY6 g/hJAumzO3qOKNhF1N71JebLmZVYOYRwhXjql1UB7YKtxKUqVu3K65tm 3l0=
c.miek.nl. 345600 IN A 85.223.71.124 c.miek.nl. 345600 IN A 85.223.71.124
c.miek.nl. 345600 IN A 85.223.71.125
c.miek.nl. 345600 IN RRSIG A 8 3 345600 20110823011301 20110724011301 12051 miek.nl. n3kcHG7PGCzxb6rt3kHrGHvwJsrTgSA3ki4QzP/6YCqBrYb5Mb/i7aLm WCisL1Q8su9B2m+3qN7IcOwu0LFvz8HgpbZkeh3rlD/H/QbBBP7Hy39r qAWRksaA8xyRzDEeRzfiKCryM532XumqxVXiJLtWHOob/u41lGkrxDGo 3Jc= c.miek.nl. 345600 IN RRSIG A 8 3 345600 20110823011301 20110724011301 12051 miek.nl. n3kcHG7PGCzxb6rt3kHrGHvwJsrTgSA3ki4QzP/6YCqBrYb5Mb/i7aLm WCisL1Q8su9B2m+3qN7IcOwu0LFvz8HgpbZkeh3rlD/H/QbBBP7Hy39r qAWRksaA8xyRzDEeRzfiKCryM532XumqxVXiJLtWHOob/u41lGkrxDGo 3Jc=
c.miek.nl. 345600 IN AAAA 2001:7b8:32a::2 c.miek.nl. 345600 IN AAAA 2001:7b8:32a::2
c.miek.nl. 345600 IN RRSIG AAAA 8 3 345600 20110823011301 20110724011301 12051 miek.nl. Ala0mHFsgM/Vq+8UOcJkKSeHcnPkaLj8E4yQkAEU2yYQBeoVubIJjG9a qmErjUmhkvVpDNAdUvEO2xofLKGogBQ/KyLGDvxADneiquFELFZOQ52W EPwOJynt2wBF+ZMxAb3+7Z5t7nnC/5KXf8j4k2DA/awOQogewMczrmxC oZM= c.miek.nl. 345600 IN RRSIG AAAA 8 3 345600 20110823011301 20110724011301 12051 miek.nl. Ala0mHFsgM/Vq+8UOcJkKSeHcnPkaLj8E4yQkAEU2yYQBeoVubIJjG9a qmErjUmhkvVpDNAdUvEO2xofLKGogBQ/KyLGDvxADneiquFELFZOQ52W EPwOJynt2wBF+ZMxAb3+7Z5t7nnC/5KXf8j4k2DA/awOQogewMczrmxC oZM=

View File

@ -118,7 +118,7 @@ func TestParse(t *testing.T) {
t.Logf("Error of nil r %v %s\n", err, test) t.Logf("Error of nil r %v %s\n", err, test)
t.Fail() t.Fail()
} }
r := z.Pop() r := z.PopRR()
if r == nil { if r == nil {
t.Log("Empty RR") t.Log("Empty RR")
t.Fail() t.Fail()

View File

@ -9,7 +9,7 @@
if rr.A == nil { if rr.A == nil {
return z, &ParseError{Error: "bad A", name: rdf[0], line: l} return z, &ParseError{Error: "bad A", name: rdf[0], line: l}
} }
z.Push(rr) z.PushRR(rr)
} }
action setAAAA { action setAAAA {
@ -21,7 +21,7 @@
if rr.AAAA == nil { if rr.AAAA == nil {
return z, &ParseError{Error: "bad AAAA", name: rdf[0], line: l} return z, &ParseError{Error: "bad AAAA", name: rdf[0], line: l}
} }
z.Push(rr) z.PushRR(rr)
} }
action setNS { action setNS {
@ -33,7 +33,7 @@
if ! IsDomainName(rdf[0]) { if ! IsDomainName(rdf[0]) {
return z, &ParseError{Error: "bad NS", name: rdf[0], line: l} return z, &ParseError{Error: "bad NS", name: rdf[0], line: l}
} }
z.Push(rr) z.PushRR(rr)
} }
action setMX { action setMX {
@ -47,7 +47,7 @@
if err != nil { if err != nil {
return z, &ParseError{Error: "bad MX", name: rdf[0], line: l} return z, &ParseError{Error: "bad MX", name: rdf[0], line: l}
} }
z.Push(rr) z.PushRR(rr)
} }
action setCNAME { action setCNAME {
@ -59,7 +59,7 @@
if ! IsDomainName(rdf[0]) { if ! IsDomainName(rdf[0]) {
return z, &ParseError{Error: "bad CNAME", name: rdf[0], line: l} return z, &ParseError{Error: "bad CNAME", name: rdf[0], line: l}
} }
z.Push(rr) z.PushRR(rr)
} }
action setSOA { action setSOA {
@ -91,7 +91,7 @@
case 4: rr.Minttl = uint32(i) case 4: rr.Minttl = uint32(i)
} }
} }
z.Push(rr) z.PushRR(rr)
} }
action setDS { action setDS {
@ -103,7 +103,7 @@
rr.Algorithm = uint8(atoi(rdf[1])) rr.Algorithm = uint8(atoi(rdf[1]))
rr.DigestType = uint8(atoi(rdf[2])) rr.DigestType = uint8(atoi(rdf[2]))
rr.Digest = rdf[3] rr.Digest = rdf[3]
z.Push(rr) z.PushRR(rr)
} }
action setDLV { action setDLV {
@ -115,7 +115,7 @@
rr.Algorithm = uint8(atoi(rdf[1])) rr.Algorithm = uint8(atoi(rdf[1]))
rr.DigestType = uint8(atoi(rdf[2])) rr.DigestType = uint8(atoi(rdf[2]))
rr.Digest = rdf[3] rr.Digest = rdf[3]
z.Push(rr) z.PushRR(rr)
} }
action setTA { action setTA {
@ -127,7 +127,7 @@
rr.Algorithm = uint8(atoi(rdf[1])) rr.Algorithm = uint8(atoi(rdf[1]))
rr.DigestType = uint8(atoi(rdf[2])) rr.DigestType = uint8(atoi(rdf[2]))
rr.Digest = rdf[3] rr.Digest = rdf[3]
z.Push(rr) z.PushRR(rr)
} }
action setDNSKEY { action setDNSKEY {
@ -153,7 +153,7 @@
} }
rr.Algorithm = uint8(i) rr.Algorithm = uint8(i)
rr.PublicKey = rdf[3] rr.PublicKey = rdf[3]
z.Push(rr) z.PushRR(rr)
} }
action setRRSIG { action setRRSIG {
@ -205,7 +205,7 @@
} }
// Check base64 TODO // Check base64 TODO
rr.Signature = rdf[8] rr.Signature = rdf[8]
z.Push(rr) z.PushRR(rr)
} }
action setNSEC { action setNSEC {
@ -220,7 +220,7 @@
// Check if its there in the map TODO // Check if its there in the map TODO
rr.TypeBitMap[i-1] = str_rr[rdf[i]] rr.TypeBitMap[i-1] = str_rr[rdf[i]]
} }
z.Push(rr) z.PushRR(rr)
} }
action setNSEC3 { action setNSEC3 {
@ -241,7 +241,7 @@
// Check if its there in the map TODO // Check if its there in the map TODO
rr.TypeBitMap[i-6] = str_rr[rdf[i]] rr.TypeBitMap[i-6] = str_rr[rdf[i]]
} }
z.Push(rr) z.PushRR(rr)
} }
action setNSEC3PARAM { action setNSEC3PARAM {
@ -267,6 +267,7 @@
rr.Iterations = uint16(i) rr.Iterations = uint16(i)
rr.Salt = rdf[3] rr.Salt = rdf[3]
rr.SaltLength = uint8(len(rr.Salt)) rr.SaltLength = uint8(len(rr.Salt))
z.PushRR(rr)
} }
action setPRT { action setPRT {

120
zone.go
View File

@ -5,39 +5,119 @@
package dns package dns
import ( import (
"container/vector" "os"
) )
const _CLASS = 2 << 16
// ZRRset is a structure that keeps several items from
// a zone file together. It helps in speeding up DNSSEC lookups.
type ZRRset struct {
RRs RRset // the RRset for this type and name
RRsigs RRset // the RRSIGs belonging to this RRset (if any)
Nsec RR // the NSEC record belonging to this RRset (if any)
Nsec3 RR // the NSEC3 record belonging to this RRset (if any)
Glue bool // when this RRset is glue, set to true
}
func NewZRRset() *ZRRset {
s := new(ZRRset)
s.RRs = NewRRset()
s.RRsigs = NewRRset()
return s
}
// Zone implements the concept of RFC 1035 master zone files. // Zone implements the concept of RFC 1035 master zone files.
type Zone struct { // This will be converted to some kind of tree structure
v vector.Vector type Zone map[string]map[int]*ZRRset
func NewZone() Zone {
z := make(Zone)
return z
} }
// Add a new RR to the zone. // Get the first value
func (z *Zone) Push(r RR) { func (z Zone) Pop() *ZRRset {
z.v.Push(r) for _, v := range z {
for _, v1 := range v {
return v1
}
}
return nil
} }
// Remove a RR from the zone. func (z Zone) PopRR() RR {
func (z *Zone) Pop() RR { s := z.Pop()
if z == nil { if s == nil {
return nil return nil
} }
return z.v.Pop().(RR) // differentiate between the type 'n stuff
return s.RRs.Pop()
} }
// Return the RR at index i of zone. func (z Zone) Len() int {
func (z *Zone) At(i int) RR { i := 0
if z == nil { for _, im := range z {
return nil for _, s := range im {
i += len(s.RRs) //+ len(s.RRsigs)
} }
return z.v.At(i).(RR) }
return i
} }
// The number of RRs in zone. // Add a new RR to the zone. First we need to find out if the
func (z *Zone) Len() int { // RR already lives inside it.
if z == nil { func (z Zone) PushRR(r RR) {
return 0 s, _ := z.LookupRR(r)
if s == nil {
s = NewZRRset()
} }
return z.v.Len() s.RRs.Push(r)
z.Push(s)
} }
// Push a new ZRRset to the zone
func (z Zone) Push(s *ZRRset) {
i := intval(s.RRs[0].Header().Class, s.RRs[0].Header().Rrtype)
if z[s.RRs[0].Header().Name] == nil {
im := make(map[int]*ZRRset) // intmap
im[i] = s
z[s.RRs[0].Header().Name] = im
return
}
im := z[s.RRs[0].Header().Name]
im[i] = s
return
}
// Lookup the RR in the zone, we are only looking at
// qname, qtype and qclass of the RR
// Considerations for wildcards
// Return NXDomain, Name error, wildcard?
// Casing!
func (z Zone) LookupRR(r RR) (*ZRRset, os.Error) {
return z.lookup(r.Header().Name, r.Header().Class, r.Header().Rrtype)
}
func (z Zone) LookupQuestion(q Question) (*ZRRset, os.Error) {
return z.lookup(q.Name, q.Qclass, q.Qtype)
}
func (z Zone) lookup(qname string, qclass, qtype uint16) (*ZRRset, os.Error) {
i := intval(qclass, qtype)
if im, ok := z[qname]; ok {
// Have an im, intmap
if s, ok := im[i]; ok {
return s, nil
}
// Name found, class/type not found
return nil, nil
}
return nil, nil
}
// Number in the second map denotes the class + type.
func intval(c, t uint16) int {
return int(c) * _CLASS + int(t)
}

175
zparse.go
View File

@ -107,12 +107,12 @@ func (zp *Parser) RR() (RR, os.Error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return z.Pop().(RR), nil return z.PopRR(), nil
} }
// Zone parses an DNS master zone file. // Zone parses an DNS master zone file.
func (zp *Parser) Zone() (z *Zone, err os.Error) { func (zp *Parser) Zone() (z Zone, err os.Error) {
z = new(Zone) z = NewZone()
data := string(zp.buf) data := string(zp.buf)
cs, p, pe := 0, 0, len(data) cs, p, pe := 0, 0, len(data)
eof := len(data) eof := len(data)
@ -143,7 +143,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
if rr.A == nil { if rr.A == nil {
return z, &ParseError{Error: "bad A", name: rdf[0], line: l} return z, &ParseError{Error: "bad A", name: rdf[0], line: l}
} }
z.Push(rr) z.PushRR(rr)
} }
// line 121 "zparse.rl" // line 121 "zparse.rl"
{ {
@ -161,7 +161,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
if rr.AAAA == nil { if rr.AAAA == nil {
return z, &ParseError{Error: "bad AAAA", name: rdf[0], line: l} return z, &ParseError{Error: "bad AAAA", name: rdf[0], line: l}
} }
z.Push(rr) z.PushRR(rr)
} }
// line 121 "zparse.rl" // line 121 "zparse.rl"
{ {
@ -169,7 +169,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
goto st141 goto st141
tr50: tr50:
// line 281 "types.rl" // line 282 "types.rl"
{ {
} }
// line 121 "zparse.rl" // line 121 "zparse.rl"
@ -188,7 +188,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
if !IsDomainName(rdf[0]) { if !IsDomainName(rdf[0]) {
return z, &ParseError{Error: "bad CNAME", name: rdf[0], line: l} return z, &ParseError{Error: "bad CNAME", name: rdf[0], line: l}
} }
z.Push(rr) z.PushRR(rr)
} }
// line 121 "zparse.rl" // line 121 "zparse.rl"
{ {
@ -206,7 +206,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
rr.Algorithm = uint8(atoi(rdf[1])) rr.Algorithm = uint8(atoi(rdf[1]))
rr.DigestType = uint8(atoi(rdf[2])) rr.DigestType = uint8(atoi(rdf[2]))
rr.Digest = rdf[3] rr.Digest = rdf[3]
z.Push(rr) z.PushRR(rr)
} }
// line 121 "zparse.rl" // line 121 "zparse.rl"
{ {
@ -214,7 +214,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
goto st141 goto st141
tr79: tr79:
// line 287 "types.rl" // line 288 "types.rl"
{ {
} }
// line 121 "zparse.rl" // line 121 "zparse.rl"
@ -247,7 +247,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
rr.Algorithm = uint8(i) rr.Algorithm = uint8(i)
rr.PublicKey = rdf[3] rr.PublicKey = rdf[3]
z.Push(rr) z.PushRR(rr)
} }
// line 121 "zparse.rl" // line 121 "zparse.rl"
{ {
@ -265,7 +265,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
rr.Algorithm = uint8(atoi(rdf[1])) rr.Algorithm = uint8(atoi(rdf[1]))
rr.DigestType = uint8(atoi(rdf[2])) rr.DigestType = uint8(atoi(rdf[2]))
rr.Digest = rdf[3] rr.Digest = rdf[3]
z.Push(rr) z.PushRR(rr)
} }
// line 121 "zparse.rl" // line 121 "zparse.rl"
{ {
@ -285,7 +285,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
if err != nil { if err != nil {
return z, &ParseError{Error: "bad MX", name: rdf[0], line: l} return z, &ParseError{Error: "bad MX", name: rdf[0], line: l}
} }
z.Push(rr) z.PushRR(rr)
} }
// line 121 "zparse.rl" // line 121 "zparse.rl"
{ {
@ -293,7 +293,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
goto st141 goto st141
tr108: tr108:
// line 290 "types.rl" // line 291 "types.rl"
{ {
} }
// line 121 "zparse.rl" // line 121 "zparse.rl"
@ -312,7 +312,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
if !IsDomainName(rdf[0]) { if !IsDomainName(rdf[0]) {
return z, &ParseError{Error: "bad NS", name: rdf[0], line: l} return z, &ParseError{Error: "bad NS", name: rdf[0], line: l}
} }
z.Push(rr) z.PushRR(rr)
} }
// line 121 "zparse.rl" // line 121 "zparse.rl"
{ {
@ -333,7 +333,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
// Check if its there in the map TODO // Check if its there in the map TODO
rr.TypeBitMap[i-1] = str_rr[rdf[i]] rr.TypeBitMap[i-1] = str_rr[rdf[i]]
} }
z.Push(rr) z.PushRR(rr)
} }
// line 121 "zparse.rl" // line 121 "zparse.rl"
{ {
@ -360,7 +360,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
// Check if its there in the map TODO // Check if its there in the map TODO
rr.TypeBitMap[i-6] = str_rr[rdf[i]] rr.TypeBitMap[i-6] = str_rr[rdf[i]]
} }
z.Push(rr) z.PushRR(rr)
} }
// line 121 "zparse.rl" // line 121 "zparse.rl"
{ {
@ -392,6 +392,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
rr.Iterations = uint16(i) rr.Iterations = uint16(i)
rr.Salt = rdf[3] rr.Salt = rdf[3]
rr.SaltLength = uint8(len(rr.Salt)) rr.SaltLength = uint8(len(rr.Salt))
z.PushRR(rr)
} }
// line 121 "zparse.rl" // line 121 "zparse.rl"
{ {
@ -399,7 +400,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
goto st141 goto st141
tr143: tr143:
// line 284 "types.rl" // line 285 "types.rl"
{ {
} }
// line 121 "zparse.rl" // line 121 "zparse.rl"
@ -458,7 +459,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
// Check base64 TODO // Check base64 TODO
rr.Signature = rdf[8] rr.Signature = rdf[8]
z.Push(rr) z.PushRR(rr)
} }
// line 121 "zparse.rl" // line 121 "zparse.rl"
{ {
@ -501,7 +502,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
rr.Minttl = uint32(i) rr.Minttl = uint32(i)
} }
} }
z.Push(rr) z.PushRR(rr)
} }
// line 121 "zparse.rl" // line 121 "zparse.rl"
{ {
@ -509,7 +510,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
goto st141 goto st141
tr167: tr167:
// line 278 "types.rl" // line 279 "types.rl"
{ {
} }
// line 121 "zparse.rl" // line 121 "zparse.rl"
@ -518,7 +519,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
goto st141 goto st141
tr175: tr175:
// line 293 "types.rl" // line 294 "types.rl"
{ {
var ( var (
i int i int
@ -554,7 +555,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
rr.Algorithm = uint8(atoi(rdf[1])) rr.Algorithm = uint8(atoi(rdf[1]))
rr.DigestType = uint8(atoi(rdf[2])) rr.DigestType = uint8(atoi(rdf[2]))
rr.Digest = rdf[3] rr.Digest = rdf[3]
z.Push(rr) z.PushRR(rr)
} }
// line 121 "zparse.rl" // line 121 "zparse.rl"
{ {
@ -562,7 +563,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
goto st141 goto st141
tr188: tr188:
// line 275 "types.rl" // line 276 "types.rl"
{ {
} }
// line 121 "zparse.rl" // line 121 "zparse.rl"
@ -583,7 +584,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 141: case 141:
// line 536 "zparse.go" // line 537 "zparse.go"
switch data[p] { switch data[p] {
case 9: case 9:
goto st1 goto st1
@ -633,7 +634,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 1: case 1:
// line 573 "zparse.go" // line 574 "zparse.go"
switch data[p] { switch data[p] {
case 9: case 9:
goto st1 goto st1
@ -704,7 +705,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 2: case 2:
// line 613 "zparse.go" // line 614 "zparse.go"
switch data[p] { switch data[p] {
case 9: case 9:
goto tr14 goto tr14
@ -729,7 +730,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 3: case 3:
// line 629 "zparse.go" // line 630 "zparse.go"
switch data[p] { switch data[p] {
case 9: case 9:
goto st3 goto st3
@ -793,7 +794,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 4: case 4:
// line 666 "zparse.go" // line 667 "zparse.go"
switch data[p] { switch data[p] {
case 9: case 9:
goto st5 goto st5
@ -834,7 +835,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 6: case 6:
// line 694 "zparse.go" // line 695 "zparse.go"
if data[p] == 10 { if data[p] == 10 {
goto tr33 goto tr33
} }
@ -852,7 +853,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 7: case 7:
// line 706 "zparse.go" // line 707 "zparse.go"
switch data[p] { switch data[p] {
case 9: case 9:
goto tr31 goto tr31
@ -933,7 +934,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 12: case 12:
// line 763 "zparse.go" // line 764 "zparse.go"
if data[p] == 10 { if data[p] == 10 {
goto tr40 goto tr40
} }
@ -951,7 +952,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 13: case 13:
// line 775 "zparse.go" // line 776 "zparse.go"
switch data[p] { switch data[p] {
case 9: case 9:
goto tr38 goto tr38
@ -974,7 +975,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 14: case 14:
// line 791 "zparse.go" // line 792 "zparse.go"
switch data[p] { switch data[p] {
case 69: case 69:
goto st15 goto st15
@ -1061,7 +1062,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 19: case 19:
// line 851 "zparse.go" // line 852 "zparse.go"
if data[p] == 10 { if data[p] == 10 {
goto tr50 goto tr50
} }
@ -1079,7 +1080,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 20: case 20:
// line 863 "zparse.go" // line 864 "zparse.go"
switch data[p] { switch data[p] {
case 9: case 9:
goto tr48 goto tr48
@ -1123,7 +1124,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 22: case 22:
// line 893 "zparse.go" // line 894 "zparse.go"
switch data[p] { switch data[p] {
case 9: case 9:
goto st22 goto st22
@ -1270,7 +1271,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 29: case 29:
// line 989 "zparse.go" // line 990 "zparse.go"
if data[p] == 10 { if data[p] == 10 {
goto tr61 goto tr61
} }
@ -1288,7 +1289,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 30: case 30:
// line 1001 "zparse.go" // line 1002 "zparse.go"
switch data[p] { switch data[p] {
case 9: case 9:
goto tr59 goto tr59
@ -1310,7 +1311,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 31: case 31:
// line 1017 "zparse.go" // line 1018 "zparse.go"
switch data[p] { switch data[p] {
case 76: case 76:
goto st32 goto st32
@ -1383,7 +1384,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 35: case 35:
// line 1067 "zparse.go" // line 1068 "zparse.go"
if data[p] == 10 { if data[p] == 10 {
goto tr70 goto tr70
} }
@ -1401,7 +1402,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 36: case 36:
// line 1079 "zparse.go" // line 1080 "zparse.go"
switch data[p] { switch data[p] {
case 9: case 9:
goto tr68 goto tr68
@ -1500,7 +1501,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 42: case 42:
// line 1148 "zparse.go" // line 1149 "zparse.go"
if data[p] == 10 { if data[p] == 10 {
goto tr79 goto tr79
} }
@ -1518,7 +1519,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 43: case 43:
// line 1160 "zparse.go" // line 1161 "zparse.go"
switch data[p] { switch data[p] {
case 9: case 9:
goto tr77 goto tr77
@ -1613,7 +1614,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 49: case 49:
// line 1227 "zparse.go" // line 1228 "zparse.go"
if data[p] == 10 { if data[p] == 10 {
goto tr87 goto tr87
} }
@ -1631,7 +1632,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 50: case 50:
// line 1239 "zparse.go" // line 1240 "zparse.go"
switch data[p] { switch data[p] {
case 9: case 9:
goto tr85 goto tr85
@ -1684,7 +1685,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 53: case 53:
// line 1276 "zparse.go" // line 1277 "zparse.go"
if data[p] == 10 { if data[p] == 10 {
goto tr92 goto tr92
} }
@ -1702,7 +1703,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 54: case 54:
// line 1288 "zparse.go" // line 1289 "zparse.go"
switch data[p] { switch data[p] {
case 9: case 9:
goto tr90 goto tr90
@ -1724,7 +1725,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 55: case 55:
// line 1304 "zparse.go" // line 1305 "zparse.go"
switch data[p] { switch data[p] {
case 88: case 88:
goto st56 goto st56
@ -1775,7 +1776,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 58: case 58:
// line 1340 "zparse.go" // line 1341 "zparse.go"
if data[p] == 10 { if data[p] == 10 {
goto tr98 goto tr98
} }
@ -1793,7 +1794,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 59: case 59:
// line 1352 "zparse.go" // line 1353 "zparse.go"
switch data[p] { switch data[p] {
case 9: case 9:
goto tr96 goto tr96
@ -1815,7 +1816,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 60: case 60:
// line 1368 "zparse.go" // line 1369 "zparse.go"
switch data[p] { switch data[p] {
case 65: case 65:
goto st61 goto st61
@ -1912,7 +1913,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 66: case 66:
// line 1436 "zparse.go" // line 1437 "zparse.go"
if data[p] == 10 { if data[p] == 10 {
goto tr108 goto tr108
} }
@ -1930,7 +1931,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 67: case 67:
// line 1448 "zparse.go" // line 1449 "zparse.go"
switch data[p] { switch data[p] {
case 9: case 9:
goto tr106 goto tr106
@ -1987,7 +1988,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 70: case 70:
// line 1487 "zparse.go" // line 1488 "zparse.go"
if data[p] == 10 { if data[p] == 10 {
goto tr114 goto tr114
} }
@ -2005,7 +2006,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 71: case 71:
// line 1499 "zparse.go" // line 1500 "zparse.go"
switch data[p] { switch data[p] {
case 9: case 9:
goto tr112 goto tr112
@ -2074,7 +2075,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 75: case 75:
// line 1547 "zparse.go" // line 1548 "zparse.go"
if data[p] == 10 { if data[p] == 10 {
goto tr121 goto tr121
} }
@ -2092,7 +2093,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 76: case 76:
// line 1559 "zparse.go" // line 1560 "zparse.go"
switch data[p] { switch data[p] {
case 9: case 9:
goto tr119 goto tr119
@ -2149,7 +2150,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 79: case 79:
// line 1598 "zparse.go" // line 1599 "zparse.go"
if data[p] == 10 { if data[p] == 10 {
goto tr127 goto tr127
} }
@ -2167,7 +2168,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 80: case 80:
// line 1610 "zparse.go" // line 1611 "zparse.go"
switch data[p] { switch data[p] {
case 9: case 9:
goto tr125 goto tr125
@ -2276,7 +2277,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 87: case 87:
// line 1687 "zparse.go" // line 1688 "zparse.go"
if data[p] == 10 { if data[p] == 10 {
goto tr136 goto tr136
} }
@ -2294,7 +2295,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 88: case 88:
// line 1699 "zparse.go" // line 1700 "zparse.go"
switch data[p] { switch data[p] {
case 9: case 9:
goto tr134 goto tr134
@ -2316,7 +2317,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 89: case 89:
// line 1715 "zparse.go" // line 1716 "zparse.go"
switch data[p] { switch data[p] {
case 84: case 84:
goto st90 goto st90
@ -2381,7 +2382,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 93: case 93:
// line 1761 "zparse.go" // line 1762 "zparse.go"
if data[p] == 10 { if data[p] == 10 {
goto tr143 goto tr143
} }
@ -2399,7 +2400,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 94: case 94:
// line 1773 "zparse.go" // line 1774 "zparse.go"
switch data[p] { switch data[p] {
case 9: case 9:
goto tr141 goto tr141
@ -2421,7 +2422,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 95: case 95:
// line 1789 "zparse.go" // line 1790 "zparse.go"
switch data[p] { switch data[p] {
case 82: case 82:
goto st96 goto st96
@ -2514,7 +2515,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 101: case 101:
// line 1855 "zparse.go" // line 1856 "zparse.go"
if data[p] == 10 { if data[p] == 10 {
goto tr152 goto tr152
} }
@ -2532,7 +2533,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 102: case 102:
// line 1867 "zparse.go" // line 1868 "zparse.go"
switch data[p] { switch data[p] {
case 9: case 9:
goto tr150 goto tr150
@ -2554,7 +2555,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 103: case 103:
// line 1883 "zparse.go" // line 1884 "zparse.go"
switch data[p] { switch data[p] {
case 79: case 79:
goto st104 goto st104
@ -2627,7 +2628,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 107: case 107:
// line 1933 "zparse.go" // line 1934 "zparse.go"
if data[p] == 10 { if data[p] == 10 {
goto tr161 goto tr161
} }
@ -2645,7 +2646,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 108: case 108:
// line 1945 "zparse.go" // line 1946 "zparse.go"
switch data[p] { switch data[p] {
case 9: case 9:
goto tr159 goto tr159
@ -2712,7 +2713,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 112: case 112:
// line 1992 "zparse.go" // line 1993 "zparse.go"
if data[p] == 10 { if data[p] == 10 {
goto tr167 goto tr167
} }
@ -2730,7 +2731,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 113: case 113:
// line 2004 "zparse.go" // line 2005 "zparse.go"
switch data[p] { switch data[p] {
case 9: case 9:
goto tr165 goto tr165
@ -2825,7 +2826,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 119: case 119:
// line 2071 "zparse.go" // line 2072 "zparse.go"
if data[p] == 10 { if data[p] == 10 {
goto tr175 goto tr175
} }
@ -2843,7 +2844,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 120: case 120:
// line 2083 "zparse.go" // line 2084 "zparse.go"
switch data[p] { switch data[p] {
case 9: case 9:
goto tr173 goto tr173
@ -2865,7 +2866,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 121: case 121:
// line 2099 "zparse.go" // line 2100 "zparse.go"
switch data[p] { switch data[p] {
case 65: case 65:
goto st122 goto st122
@ -2920,7 +2921,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 124: case 124:
// line 2137 "zparse.go" // line 2138 "zparse.go"
if data[p] == 10 { if data[p] == 10 {
goto tr182 goto tr182
} }
@ -2938,7 +2939,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 125: case 125:
// line 2149 "zparse.go" // line 2150 "zparse.go"
switch data[p] { switch data[p] {
case 9: case 9:
goto tr180 goto tr180
@ -3005,7 +3006,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 129: case 129:
// line 2196 "zparse.go" // line 2197 "zparse.go"
if data[p] == 10 { if data[p] == 10 {
goto tr188 goto tr188
} }
@ -3023,7 +3024,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 130: case 130:
// line 2208 "zparse.go" // line 2209 "zparse.go"
switch data[p] { switch data[p] {
case 9: case 9:
goto tr186 goto tr186
@ -3046,7 +3047,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 131: case 131:
// line 2224 "zparse.go" // line 2225 "zparse.go"
switch data[p] { switch data[p] {
case 83: case 83:
goto st21 goto st21
@ -3067,7 +3068,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 132: case 132:
// line 2239 "zparse.go" // line 2240 "zparse.go"
switch data[p] { switch data[p] {
case 78: case 78:
goto st21 goto st21
@ -3091,7 +3092,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 133: case 133:
// line 2256 "zparse.go" // line 2257 "zparse.go"
switch data[p] { switch data[p] {
case 69: case 69:
goto st15 goto st15
@ -3134,7 +3135,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 135: case 135:
// line 2285 "zparse.go" // line 2286 "zparse.go"
switch data[p] { switch data[p] {
case 9: case 9:
goto st135 goto st135
@ -3194,7 +3195,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 136: case 136:
// line 2319 "zparse.go" // line 2320 "zparse.go"
switch data[p] { switch data[p] {
case 9: case 9:
goto tr193 goto tr193
@ -3221,7 +3222,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 137: case 137:
// line 2337 "zparse.go" // line 2338 "zparse.go"
switch data[p] { switch data[p] {
case 83: case 83:
goto st134 goto st134
@ -3245,7 +3246,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 138: case 138:
// line 2354 "zparse.go" // line 2355 "zparse.go"
switch data[p] { switch data[p] {
case 78: case 78:
goto st134 goto st134
@ -3266,7 +3267,7 @@ func (zp *Parser) Zone() (z *Zone, err os.Error) {
} }
fallthrough fallthrough
case 139: case 139:
// line 2369 "zparse.go" // line 2370 "zparse.go"
switch data[p] { switch data[p] {
case 9: case 9:
goto tr195 goto tr195

View File

@ -99,12 +99,12 @@ func (zp *Parser) RR() (RR, os.Error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return z.Pop().(RR), nil return z.PopRR(), nil
} }
// Zone parses an DNS master zone file. // Zone parses an DNS master zone file.
func (zp *Parser) Zone() (z *Zone, err os.Error) { func (zp *Parser) Zone() (z Zone, err os.Error) {
z = new(Zone) z = NewZone()
data := string(zp.buf) data := string(zp.buf)
cs, p, pe := 0, 0, len(data) cs, p, pe := 0, 0, len(data)
eof := len(data) eof := len(data)