If we add a dot to a name, be sure to remove one from the length

This commit is contained in:
Miek Gieben 2012-02-05 11:33:55 +01:00
parent cb4d52c110
commit 77b60231e7
5 changed files with 35 additions and 29 deletions

View File

@ -237,12 +237,12 @@ func (c *Client) Exchange(m *Msg, a string) (r *Msg, err error) {
case "tcp":
in = make([]byte, MaxMsgSize)
case "udp":
size := UDPMsgSize
for _, r := range m.Extra {
if r.Header().Rrtype == TypeOPT {
size = int(r.(*RR_OPT).UDPSize())
}
}
size := UDPMsgSize
for _, r := range m.Extra {
if r.Header().Rrtype == TypeOPT {
size = int(r.(*RR_OPT).UDPSize())
}
}
in = make([]byte, size)
}
if n, err = c.ExchangeBuffer(out, a, in); err != nil {

View File

@ -201,16 +201,20 @@ func (dns *Msg) IsEdns0() (ok bool) {
// When false the returned labelcount and length is 0 and 0.
func IsDomainName(s string) (uint8, uint8, bool) { // copied from net package.
// See RFC 1035, RFC 3696.
l := len(s)
l := len(s)
if l == 0 || l > 255 {
return 0, 0, false
}
// Simplify checking loop: make the name end in a dot
// Don't call Fqdn() to save another len(s)
if s[l-1] != '.' {
s += "."
l++
}
longer := 0
// Simplify checking loop: make the name end in a dot.
// Don't call Fqdn() to save another len(s).
// Keep in mind that if we do this, we report a longer
// length
if s[l-1] != '.' {
s += "."
l++
longer = 1
}
last := byte('.')
ok := false // ok once we've seen a letter
partlen := 0
@ -219,7 +223,7 @@ func IsDomainName(s string) (uint8, uint8, bool) { // copied from net package.
c := s[i]
switch {
default:
return 0, uint8(l), false
return 0, uint8(l - longer), false
case 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || c == '_' || c == '*':
ok = true
partlen++
@ -231,27 +235,27 @@ func IsDomainName(s string) (uint8, uint8, bool) { // copied from net package.
case c == '-':
// byte before dash cannot be dot
if last == '.' {
return 0, uint8(l), false
return 0, uint8(l - longer), false
}
partlen++
case c == '.':
// byte before dot cannot be dot, dash
if last == '.' || last == '-' {
return 0, uint8(l), false
return 0, uint8(l - longer), false
}
if last == '\\' { // Ok, escaped dot.
partlen++
break
}
if partlen > 63 || partlen == 0 {
return 0, uint8(l), false
return 0, uint8(l - longer), false
}
partlen = 0
labels++
}
last = c
}
return labels, uint8(l), ok
return labels, uint8(l - longer), ok
}
// IsFqdn checks if a domain name is fully qualified

10
dns.go
View File

@ -67,11 +67,11 @@ import (
)
const (
Year68 = 1 << 32 // For RFC1982 (Serial Arithmetic) calculations in 32 bits.
DefaultMsgSize = 4096 // Standard default for larger than 512 packets.
UDPMsgSize = 512 // Default buffer size for servers receiving UDP packets.
MaxMsgSize = 65536 // Largest possible DNS packet.
DefaultTtl = 3600 // Default TTL.
Year68 = 1 << 32 // For RFC1982 (Serial Arithmetic) calculations in 32 bits.
DefaultMsgSize = 4096 // Standard default for larger than 512 packets.
UDPMsgSize = 512 // Default buffer size for servers receiving UDP packets.
MaxMsgSize = 65536 // Largest possible DNS packet.
DefaultTtl = 3600 // Default TTL.
)
// Error represents a DNS error

8
msg.go
View File

@ -808,10 +808,10 @@ func unpackStructValue(val reflect.Value, msg []byte, off int) (off1 int, ok boo
default:
consumed = 0 // TODO, maybe error?
}
if off+rdlength-consumed > lenmsg {
println("dns: failure unpacking base64")
return lenmsg, false
}
if off+rdlength-consumed > lenmsg {
println("dns: failure unpacking base64")
return lenmsg, false
}
s = unpackBase64(msg[off : off+rdlength-consumed])
off += rdlength - consumed
case "cdomain-name":

View File

@ -162,11 +162,13 @@ func parseZone(r io.Reader, f string, t chan Token, include int) {
case _OWNER:
h.Name = l.token
_, ld, ok := IsDomainName(l.token)
if !ok {
if !ok {
t <- Token{Error: &ParseError{f, "bad owner name", l}}
return
}
if h.Name[ld-1] != '.' {
println(l.token)
println(len(l.token), ld)
if h.Name[ld-1] != '.' {
h.Name += origin
}
st = _EXPECT_OWNER_BL