From 77b60231e731639d003ccc3f0f943871b1fca34a Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Sun, 5 Feb 2012 11:33:55 +0100 Subject: [PATCH] If we add a dot to a name, be sure to remove one from the length --- client.go | 12 ++++++------ defaults.go | 28 ++++++++++++++++------------ dns.go | 10 +++++----- msg.go | 8 ++++---- zscan.go | 6 ++++-- 5 files changed, 35 insertions(+), 29 deletions(-) diff --git a/client.go b/client.go index ddee1ef4..e046e6c4 100644 --- a/client.go +++ b/client.go @@ -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 { diff --git a/defaults.go b/defaults.go index 96423cad..e6bf5343 100644 --- a/defaults.go +++ b/defaults.go @@ -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 diff --git a/dns.go b/dns.go index 29c6e1f3..f4ab6600 100644 --- a/dns.go +++ b/dns.go @@ -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 diff --git a/msg.go b/msg.go index 93bbc80a..cbccc8b7 100644 --- a/msg.go +++ b/msg.go @@ -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": diff --git a/zscan.go b/zscan.go index e2d82321..37d4c2be 100644 --- a/zscan.go +++ b/zscan.go @@ -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