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": case "tcp":
in = make([]byte, MaxMsgSize) in = make([]byte, MaxMsgSize)
case "udp": case "udp":
size := UDPMsgSize size := UDPMsgSize
for _, r := range m.Extra { for _, r := range m.Extra {
if r.Header().Rrtype == TypeOPT { if r.Header().Rrtype == TypeOPT {
size = int(r.(*RR_OPT).UDPSize()) size = int(r.(*RR_OPT).UDPSize())
} }
} }
in = make([]byte, size) in = make([]byte, size)
} }
if n, err = c.ExchangeBuffer(out, a, in); err != nil { 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. // When false the returned labelcount and length is 0 and 0.
func IsDomainName(s string) (uint8, uint8, bool) { // copied from net package. func IsDomainName(s string) (uint8, uint8, bool) { // copied from net package.
// See RFC 1035, RFC 3696. // See RFC 1035, RFC 3696.
l := len(s) l := len(s)
if l == 0 || l > 255 { if l == 0 || l > 255 {
return 0, 0, false return 0, 0, false
} }
// Simplify checking loop: make the name end in a dot longer := 0
// Don't call Fqdn() to save another len(s) // Simplify checking loop: make the name end in a dot.
if s[l-1] != '.' { // Don't call Fqdn() to save another len(s).
s += "." // Keep in mind that if we do this, we report a longer
l++ // length
} if s[l-1] != '.' {
s += "."
l++
longer = 1
}
last := byte('.') last := byte('.')
ok := false // ok once we've seen a letter ok := false // ok once we've seen a letter
partlen := 0 partlen := 0
@ -219,7 +223,7 @@ func IsDomainName(s string) (uint8, uint8, bool) { // copied from net package.
c := s[i] c := s[i]
switch { switch {
default: default:
return 0, uint8(l), false return 0, uint8(l - longer), false
case 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || c == '_' || c == '*': case 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || c == '_' || c == '*':
ok = true ok = true
partlen++ partlen++
@ -231,27 +235,27 @@ func IsDomainName(s string) (uint8, uint8, bool) { // copied from net package.
case c == '-': case c == '-':
// byte before dash cannot be dot // byte before dash cannot be dot
if last == '.' { if last == '.' {
return 0, uint8(l), false return 0, uint8(l - longer), false
} }
partlen++ partlen++
case c == '.': case c == '.':
// byte before dot cannot be dot, dash // byte before dot cannot be dot, dash
if last == '.' || last == '-' { if last == '.' || last == '-' {
return 0, uint8(l), false return 0, uint8(l - longer), false
} }
if last == '\\' { // Ok, escaped dot. if last == '\\' { // Ok, escaped dot.
partlen++ partlen++
break break
} }
if partlen > 63 || partlen == 0 { if partlen > 63 || partlen == 0 {
return 0, uint8(l), false return 0, uint8(l - longer), false
} }
partlen = 0 partlen = 0
labels++ labels++
} }
last = c last = c
} }
return labels, uint8(l), ok return labels, uint8(l - longer), ok
} }
// IsFqdn checks if a domain name is fully qualified // IsFqdn checks if a domain name is fully qualified

10
dns.go
View File

@ -67,11 +67,11 @@ import (
) )
const ( const (
Year68 = 1 << 32 // For RFC1982 (Serial Arithmetic) calculations in 32 bits. Year68 = 1 << 32 // For RFC1982 (Serial Arithmetic) calculations in 32 bits.
DefaultMsgSize = 4096 // Standard default for larger than 512 packets. DefaultMsgSize = 4096 // Standard default for larger than 512 packets.
UDPMsgSize = 512 // Default buffer size for servers receiving UDP packets. UDPMsgSize = 512 // Default buffer size for servers receiving UDP packets.
MaxMsgSize = 65536 // Largest possible DNS packet. MaxMsgSize = 65536 // Largest possible DNS packet.
DefaultTtl = 3600 // Default TTL. DefaultTtl = 3600 // Default TTL.
) )
// Error represents a DNS error // 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: default:
consumed = 0 // TODO, maybe error? consumed = 0 // TODO, maybe error?
} }
if off+rdlength-consumed > lenmsg { if off+rdlength-consumed > lenmsg {
println("dns: failure unpacking base64") println("dns: failure unpacking base64")
return lenmsg, false return lenmsg, false
} }
s = unpackBase64(msg[off : off+rdlength-consumed]) s = unpackBase64(msg[off : off+rdlength-consumed])
off += rdlength - consumed off += rdlength - consumed
case "cdomain-name": case "cdomain-name":

View File

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