Implement $TTL

This commit is contained in:
Miek Gieben 2011-12-18 17:58:06 +01:00
parent 925d38c689
commit 54c7e4d1a9
1 changed files with 57 additions and 22 deletions

View File

@ -26,15 +26,15 @@ const (
_RRTYPE _RRTYPE
_OWNER _OWNER
_CLASS _CLASS
_DIRORIGIN // $ORIGIN _DIRORIGIN // $ORIGIN
_DIRTTL // $TTL _DIRTTL // $TTL
_INCLUDE // $INCLUDE _DIRINCLUDE // $INCLUDE
// Privatekey file // Privatekey file
_VALUE _VALUE
_KEY _KEY
_EXPECT_OWNER // Ownername _EXPECT_OWNER_DIR // Ownername
_EXPECT_OWNER_BL // Whitespace after the ownername _EXPECT_OWNER_BL // Whitespace after the ownername
_EXPECT_ANY // Expect rrtype, ttl or class _EXPECT_ANY // Expect rrtype, ttl or class
_EXPECT_ANY_NOCLASS // Expect rrtype or ttl _EXPECT_ANY_NOCLASS // Expect rrtype or ttl
@ -44,6 +44,8 @@ const (
_EXPECT_RRTYPE // Expect rrtype _EXPECT_RRTYPE // Expect rrtype
_EXPECT_RRTYPE_BL // Whitespace BEFORE rrtype _EXPECT_RRTYPE_BL // Whitespace BEFORE rrtype
_EXPECT_RDATA // The first element of the rdata _EXPECT_RDATA // The first element of the rdata
_EXPECT_DIRTTL_BL // Space after directive $TTL
_EXPECT_DIRTTL // Directive $TTL
) )
// ParseError contains the parse error and the location in the io.Reader // ParseError contains the parse error and the location in the io.Reader
@ -114,9 +116,10 @@ func ParseZone(r io.Reader, t chan Token) {
// 5. _OWNER _ _CLASS _ _STRING _ _RRTYPE -> class/ttl (reversed) // 5. _OWNER _ _CLASS _ _STRING _ _RRTYPE -> class/ttl (reversed)
// After detecting these, we know the _RRTYPE so we can jump to functions // After detecting these, we know the _RRTYPE so we can jump to functions
// handling the rdata for each of these types. // handling the rdata for each of these types.
st := _EXPECT_OWNER st := _EXPECT_OWNER_DIR
var h RR_Header var h RR_Header
var ok bool var ok bool
var defttl uint32 = DefaultTtl
for l := range c { for l := range c {
if _DEBUG { if _DEBUG {
fmt.Printf("[%v]\n", l) fmt.Printf("[%v]\n", l)
@ -128,21 +131,40 @@ func ParseZone(r io.Reader, t chan Token) {
} }
switch st { switch st {
case _EXPECT_OWNER: case _EXPECT_OWNER_DIR:
// Set the defaults here // We can also expect a directive, like $TTL or $ORIGIN
h.Ttl = DefaultTtl h.Ttl = defttl
h.Class = ClassINET h.Class = ClassINET
switch l.value { switch l.value {
case _NEWLINE: // Empty line case _NEWLINE: // Empty line
st = _EXPECT_OWNER st = _EXPECT_OWNER_DIR
case _OWNER: case _OWNER:
h.Name = l.token h.Name = l.token
st = _EXPECT_OWNER_BL st = _EXPECT_OWNER_BL
case _DIRTTL:
st = _EXPECT_DIRTTL_BL
default: default:
t <- Token{Error: &ParseError{"Error at the start", l}} t <- Token{Error: &ParseError{"Error at the start", l}}
return return
//st = _EXPECT_OWNER
} }
case _EXPECT_DIRTTL_BL:
if l.value != _BLANK {
t <- Token{Error: &ParseError{"No blank after $-directive", l}}
return
}
st = _EXPECT_DIRTTL
case _EXPECT_DIRTTL:
if l.value != _STRING {
t <- Token{Error: &ParseError{"Expecting $TTL value, not this...", l}}
return
}
if ttl, ok := stringToTtl(l, t); !ok {
return
} else {
defttl = ttl
}
st = _EXPECT_OWNER_DIR
case _EXPECT_OWNER_BL: case _EXPECT_OWNER_BL:
if l.value != _BLANK { if l.value != _BLANK {
t <- Token{Error: &ParseError{"No blank after owner", l}} t <- Token{Error: &ParseError{"No blank after owner", l}}
@ -162,12 +184,10 @@ func ParseZone(r io.Reader, t chan Token) {
} }
st = _EXPECT_ANY_NOCLASS_BL st = _EXPECT_ANY_NOCLASS_BL
case _STRING: // TTL is this case case _STRING: // TTL is this case
ttl, ok := strconv.Atoi(l.token) if ttl, ok := stringToTtl(l, t); !ok {
if ok != nil {
t <- Token{Error: &ParseError{"Ownername seen, not a TTL", l}}
return return
} else { } else {
h.Ttl = uint32(ttl) h.Ttl = ttl
} }
st = _EXPECT_ANY_NOTTL_BL st = _EXPECT_ANY_NOTTL_BL
default: default:
@ -202,12 +222,10 @@ func ParseZone(r io.Reader, t chan Token) {
case _EXPECT_ANY_NOCLASS: case _EXPECT_ANY_NOCLASS:
switch l.value { switch l.value {
case _STRING: // TTL case _STRING: // TTL
ttl, ok := strconv.Atoi(l.token) if ttl, ok := stringToTtl(l, t); !ok {
if ok != nil {
t <- Token{Error: &ParseError{"Class seen, not a TTL", l}}
return return
} else { } else {
h.Ttl = uint32(ttl) h.Ttl = ttl
} }
st = _EXPECT_RRTYPE_BL st = _EXPECT_RRTYPE_BL
case _RRTYPE: case _RRTYPE:
@ -243,7 +261,7 @@ func ParseZone(r io.Reader, t chan Token) {
return return
} }
t <- Token{Rr: r} t <- Token{Rr: r}
st = _EXPECT_OWNER st = _EXPECT_OWNER_DIR
} }
} }
} }
@ -262,6 +280,8 @@ func (l lex) String() string {
return "O:" + l.token + "$" return "O:" + l.token + "$"
case _CLASS: case _CLASS:
return "C:" + l.token + "$" return "C:" + l.token + "$"
case _DIRTTL:
return "T:" + l.token + "$"
} }
return "" return ""
} }
@ -293,6 +313,11 @@ func zlexer(s scanner.Scanner, c chan lex) {
// If we have a string and its the first, make it an owner // If we have a string and its the first, make it an owner
l.value = _OWNER l.value = _OWNER
l.token = str l.token = str
if str[0] == '$' {
if str == "$TTL" {
l.value = _DIRTTL
}
}
c <- l c <- l
} else { } else {
l.value = _STRING l.value = _STRING
@ -333,9 +358,9 @@ func zlexer(s scanner.Scanner, c chan lex) {
// If not in a brace this ends the comment AND the RR // If not in a brace this ends the comment AND the RR
if brace == 0 { if brace == 0 {
owner = true owner = true
l.value = _NEWLINE l.value = _NEWLINE
l.token = "\n" l.token = "\n"
c <- l c <- l
} }
break break
} }
@ -400,3 +425,13 @@ func zlexer(s scanner.Scanner, c chan lex) {
tok = s.Scan() tok = s.Scan()
} }
} }
func stringToTtl(l lex, t chan Token) (uint32, bool) {
if ttl, ok := strconv.Atoi(l.token); ok != nil {
t <- Token{Error: &ParseError{"Not a TTL", l}}
return 0, false
} else {
return uint32(ttl), true
}
panic("not reached")
}