From ecfd5451a9e27f76ae8ad93f07293bf4a453cae4 Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Sun, 8 Jan 2012 15:54:33 +0100 Subject: [PATCH] Remove the Labels() function. This is now handled inside IsDomainName, which really parses the name and then (also) returns the number of labels found. --- defaults.go | 78 +++++++++++++++++++++++------------------------------ dns.go | 16 ++--------- dnssec.go | 4 +-- zscan.go | 6 ++--- zscan_rr.go | 32 +++++++++++----------- 5 files changed, 57 insertions(+), 79 deletions(-) diff --git a/defaults.go b/defaults.go index 540f41ea..ef56a8b9 100644 --- a/defaults.go +++ b/defaults.go @@ -197,84 +197,74 @@ func (dns *Msg) IsEdns0() (ok bool) { } // IsDomainName checks if s is a valid domainname, it returns -// true and a length, when a domain name is valid. When false -// ithe returned length isn't specified. -func IsDomainName(s string) (bool, int) { // copied from net package. +// the number of labels and true, when a domain name is valid. When false +// the returned labelcount isn't specified. +func IsDomainName(s string) (int, bool) { // copied from net package. // See RFC 1035, RFC 3696. if len(s) == 0 { - return false, 0 + return 0, false } - if len(s) > 255 { // Not true...? - return false, 0 + if len(s) > 255 { // Not true...? + return 0, false } - if !Fqdn(s) { // simplify checking loop: make name end in dot - s += "." - } - + s = Fqdn(s) // simplify checking loop: make name end in dot last := byte('.') ok := false // ok once we've seen a letter partlen := 0 - n := 0 + labels := 0 for i := 0; i < len(s); i++ { c := s[i] switch { default: - return false, 0 + return 0, false case 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || c == '_' || c == '*': ok = true partlen++ - n++ - case c == '\\': - // Ok + case c == '\\': + // Ok case '0' <= c && c <= '9': // fine partlen++ - n++ case c == '-': // byte before dash cannot be dot if last == '.' { - return false, 0 + return 0, false } partlen++ case c == '.': // byte before dot cannot be dot, dash if last == '.' || last == '-' { - return false, 0 + return 0, false + } + if last == '\\' { // Ok, escaped dot. + partlen++ + break } - if last == '\\' { // Ok, escaped dot. - partlen++ - n++ - break - } if partlen > 63 || partlen == 0 { - return false, 0 + return 0, false } partlen = 0 - n++ + labels++ } last = c } - return ok, n + return labels, ok } -// Return the number of labels in a domain name. -// Need to add these kind of function in a structured way. TODO(mg) -func Labels(a string) (c uint8) { - // walk the string and count the dots - // except when it is escaped - esc := false - for _, v := range a { - switch v { - case '.': - if esc { - esc = !esc - continue - } - c++ - case '\\': - esc = true - } +// IsFqdn checks if a domain name is fully qualified +func IsFqdn(s string) bool { + if len(s) == 0 { + return false // ? } - return + return s[len(s)-1] == '.' +} + +// Fqdns return the fully qualified domain name from s. +// Is s is already fq, then it behaves as the identity function. +func Fqdn(s string) string { + if IsFqdn(s) { + return s + } + return s + "." } diff --git a/dns.go b/dns.go index 2ee328ae..4f3e3ed4 100644 --- a/dns.go +++ b/dns.go @@ -219,12 +219,8 @@ func zoneMatch(pattern, zone string) (ok bool) { if len(zone) == 0 { zone = "." } - if pattern[len(pattern)-1] != '.' { - pattern += "." - } - if zone[len(zone)-1] != '.' { - zone += "." - } + pattern = Fqdn(pattern) + zone = Fqdn(zone) i := 0 for { ok = pattern[len(pattern)-1-i] == zone[len(zone)-1-i] @@ -240,11 +236,3 @@ func zoneMatch(pattern, zone string) (ok bool) { } return } - -// Fqdn checks if a domain name is fully qualified -func Fqdn(s string) bool { - if len(s) == 0 { - return false // ? - } - return s[len(s)-1] == '.' -} diff --git a/dnssec.go b/dnssec.go index 1bfe3d4a..9f449176 100644 --- a/dnssec.go +++ b/dnssec.go @@ -188,9 +188,9 @@ func (s *RR_RRSIG) Sign(k PrivateKey, rrset RRset) error { s.OrigTtl = rrset[0].Header().Ttl s.TypeCovered = rrset[0].Header().Rrtype s.TypeCovered = rrset[0].Header().Rrtype - s.Labels = Labels(rrset[0].Header().Name) + s.Labels, _ := IsDomainName(rrset[0].Header().Name) if strings.HasPrefix(rrset[0].Header().Name, "*") { - s.Labels-- // wildcards, remove from label count + s.Labels-- // wildcard, remove from label count } sigwire := new(rrsigWireFmt) diff --git a/zscan.go b/zscan.go index cab4ded5..106ac8c8 100644 --- a/zscan.go +++ b/zscan.go @@ -147,11 +147,11 @@ func parseZone(r io.Reader, t chan Token) { st = _EXPECT_OWNER_DIR case _OWNER: h.Name = l.token - if ok, _ := IsDomainName(l.token); !ok { + if _, ok := IsDomainName(l.token); !ok { t <- Token{Error: &ParseError{"bad owner name", l}} return } - if !Fqdn(h.Name) { + if !IsFqdn(h.Name) { h.Name += origin } st = _EXPECT_OWNER_BL @@ -191,7 +191,7 @@ func parseZone(r io.Reader, t chan Token) { t <- Token{Error: &ParseError{"Expecting $ORIGIN value, not this...", l}} return } - if !Fqdn(l.token) { + if !IsFqdn(l.token) { origin = l.token + origin // Append old origin if the new one isn't a fqdn } else { origin = l.token diff --git a/zscan_rr.go b/zscan_rr.go index 1bea9522..2aaf61c8 100644 --- a/zscan_rr.go +++ b/zscan_rr.go @@ -123,10 +123,10 @@ func setNS(h RR_Header, c chan lex, o string) (RR, *ParseError) { l := <-c rr.Ns = l.token - if ok, _ := IsDomainName(l.token); !ok { + if _, ok := IsDomainName(l.token); !ok { return nil, &ParseError{"bad NS Ns", l} } - if !Fqdn(rr.Ns) { + if !IsFqdn(rr.Ns) { rr.Ns += o } return rr, nil @@ -145,10 +145,10 @@ func setMX(h RR_Header, c chan lex, o string) (RR, *ParseError) { <-c // _BLANK l = <-c // _STRING rr.Mx = l.token - if ok, _ := IsDomainName(l.token); !ok { + if _, ok := IsDomainName(l.token); !ok { return nil, &ParseError{"bad MX Mx", l} } - if !Fqdn(rr.Mx) { + if !IsFqdn(rr.Mx) { rr.Mx += o } return rr, nil @@ -160,10 +160,10 @@ func setCNAME(h RR_Header, c chan lex, o string) (RR, *ParseError) { l := <-c rr.Cname = l.token - if ok, _ := IsDomainName(l.token); !ok { + if _, ok := IsDomainName(l.token); !ok { return nil, &ParseError{"bad CNAME", l} } - if !Fqdn(rr.Cname) { + if !IsFqdn(rr.Cname) { rr.Cname += o } return rr, nil @@ -176,19 +176,19 @@ func setSOA(h RR_Header, c chan lex, o string) (RR, *ParseError) { l := <-c rr.Ns = l.token <-c // _BLANK - if ok, _ := IsDomainName(l.token); !ok { + if _, ok := IsDomainName(l.token); !ok { return nil, &ParseError{"bad SOA mname", l} } - if !Fqdn(rr.Ns) { + if !IsFqdn(rr.Ns) { rr.Ns += o } l = <-c rr.Mbox = l.token - if ok, _ := IsDomainName(l.token); !ok { + if _, ok := IsDomainName(l.token); !ok { return nil, &ParseError{"bad SOA rname", l} } - if !Fqdn(rr.Mbox) { + if !IsFqdn(rr.Mbox) { rr.Mbox += o } <-c // _BLANK @@ -274,10 +274,10 @@ func setRRSIG(h RR_Header, c chan lex, o string) (RR, *ParseError) { <-c // _BLANK l = <-c rr.SignerName = l.token - if ok, _ := IsDomainName(l.token); !ok { + if _, ok := IsDomainName(l.token); !ok { return nil, &ParseError{"bad RRSIG signername", l} } - if !Fqdn(rr.SignerName) { + if !IsFqdn(rr.SignerName) { rr.SignerName += o } // Get the remaining data until we see a NEWLINE @@ -304,10 +304,10 @@ func setNSEC(h RR_Header, c chan lex, o string) (RR, *ParseError) { l := <-c rr.NextDomain = l.token - if ok, _ := IsDomainName(l.token); !ok { + if _, ok := IsDomainName(l.token); !ok { return nil, &ParseError{"bad NSEC nextdomain", l} } - if !Fqdn(rr.NextDomain) { + if !IsFqdn(rr.NextDomain) { rr.NextDomain += o } @@ -364,10 +364,10 @@ func setNSEC3(h RR_Header, c chan lex, o string) (RR, *ParseError) { l = <-c rr.HashLength = uint8(len(l.token)) rr.NextDomain = l.token - if ok, _ := IsDomainName(l.token); !ok { + if _, ok := IsDomainName(l.token); !ok { return nil, &ParseError{"bad NSEC nextdomain", l} } - if !Fqdn(rr.NextDomain) { + if !IsFqdn(rr.NextDomain) { rr.NextDomain += o }