Remove the Labels() function.
This is now handled inside IsDomainName, which really parses the name and then (also) returns the number of labels found.
This commit is contained in:
parent
e522a6daf7
commit
ecfd5451a9
78
defaults.go
78
defaults.go
|
@ -197,84 +197,74 @@ func (dns *Msg) IsEdns0() (ok bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsDomainName checks if s is a valid domainname, it returns
|
// IsDomainName checks if s is a valid domainname, it returns
|
||||||
// true and a length, when a domain name is valid. When false
|
// the number of labels and true, when a domain name is valid. When false
|
||||||
// ithe returned length isn't specified.
|
// the returned labelcount isn't specified.
|
||||||
func IsDomainName(s string) (bool, int) { // copied from net package.
|
func IsDomainName(s string) (int, bool) { // copied from net package.
|
||||||
// See RFC 1035, RFC 3696.
|
// See RFC 1035, RFC 3696.
|
||||||
if len(s) == 0 {
|
if len(s) == 0 {
|
||||||
return false, 0
|
return 0, false
|
||||||
}
|
}
|
||||||
if len(s) > 255 { // Not true...?
|
if len(s) > 255 { // Not true...?
|
||||||
return false, 0
|
return 0, false
|
||||||
}
|
}
|
||||||
if !Fqdn(s) { // simplify checking loop: make name end in dot
|
s = Fqdn(s) // simplify checking loop: make name end in dot
|
||||||
s += "."
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
||||||
n := 0
|
labels := 0
|
||||||
for i := 0; i < len(s); i++ {
|
for i := 0; i < len(s); i++ {
|
||||||
c := s[i]
|
c := s[i]
|
||||||
switch {
|
switch {
|
||||||
default:
|
default:
|
||||||
return false, 0
|
return 0, 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++
|
||||||
n++
|
case c == '\\':
|
||||||
case c == '\\':
|
// Ok
|
||||||
// Ok
|
|
||||||
case '0' <= c && c <= '9':
|
case '0' <= c && c <= '9':
|
||||||
// fine
|
// fine
|
||||||
partlen++
|
partlen++
|
||||||
n++
|
|
||||||
case c == '-':
|
case c == '-':
|
||||||
// byte before dash cannot be dot
|
// byte before dash cannot be dot
|
||||||
if last == '.' {
|
if last == '.' {
|
||||||
return false, 0
|
return 0, 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 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 {
|
if partlen > 63 || partlen == 0 {
|
||||||
return false, 0
|
return 0, false
|
||||||
}
|
}
|
||||||
partlen = 0
|
partlen = 0
|
||||||
n++
|
labels++
|
||||||
}
|
}
|
||||||
last = c
|
last = c
|
||||||
}
|
}
|
||||||
|
|
||||||
return ok, n
|
return labels, ok
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the number of labels in a domain name.
|
// IsFqdn checks if a domain name is fully qualified
|
||||||
// Need to add these kind of function in a structured way. TODO(mg)
|
func IsFqdn(s string) bool {
|
||||||
func Labels(a string) (c uint8) {
|
if len(s) == 0 {
|
||||||
// walk the string and count the dots
|
return false // ?
|
||||||
// except when it is escaped
|
|
||||||
esc := false
|
|
||||||
for _, v := range a {
|
|
||||||
switch v {
|
|
||||||
case '.':
|
|
||||||
if esc {
|
|
||||||
esc = !esc
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
c++
|
|
||||||
case '\\':
|
|
||||||
esc = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
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 + "."
|
||||||
}
|
}
|
||||||
|
|
16
dns.go
16
dns.go
|
@ -219,12 +219,8 @@ func zoneMatch(pattern, zone string) (ok bool) {
|
||||||
if len(zone) == 0 {
|
if len(zone) == 0 {
|
||||||
zone = "."
|
zone = "."
|
||||||
}
|
}
|
||||||
if pattern[len(pattern)-1] != '.' {
|
pattern = Fqdn(pattern)
|
||||||
pattern += "."
|
zone = Fqdn(zone)
|
||||||
}
|
|
||||||
if zone[len(zone)-1] != '.' {
|
|
||||||
zone += "."
|
|
||||||
}
|
|
||||||
i := 0
|
i := 0
|
||||||
for {
|
for {
|
||||||
ok = pattern[len(pattern)-1-i] == zone[len(zone)-1-i]
|
ok = pattern[len(pattern)-1-i] == zone[len(zone)-1-i]
|
||||||
|
@ -240,11 +236,3 @@ func zoneMatch(pattern, zone string) (ok bool) {
|
||||||
}
|
}
|
||||||
return
|
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] == '.'
|
|
||||||
}
|
|
||||||
|
|
|
@ -188,9 +188,9 @@ func (s *RR_RRSIG) Sign(k PrivateKey, rrset RRset) error {
|
||||||
s.OrigTtl = rrset[0].Header().Ttl
|
s.OrigTtl = rrset[0].Header().Ttl
|
||||||
s.TypeCovered = rrset[0].Header().Rrtype
|
s.TypeCovered = rrset[0].Header().Rrtype
|
||||||
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, "*") {
|
if strings.HasPrefix(rrset[0].Header().Name, "*") {
|
||||||
s.Labels-- // wildcards, remove from label count
|
s.Labels-- // wildcard, remove from label count
|
||||||
}
|
}
|
||||||
|
|
||||||
sigwire := new(rrsigWireFmt)
|
sigwire := new(rrsigWireFmt)
|
||||||
|
|
6
zscan.go
6
zscan.go
|
@ -147,11 +147,11 @@ func parseZone(r io.Reader, t chan Token) {
|
||||||
st = _EXPECT_OWNER_DIR
|
st = _EXPECT_OWNER_DIR
|
||||||
case _OWNER:
|
case _OWNER:
|
||||||
h.Name = l.token
|
h.Name = l.token
|
||||||
if ok, _ := IsDomainName(l.token); !ok {
|
if _, ok := IsDomainName(l.token); !ok {
|
||||||
t <- Token{Error: &ParseError{"bad owner name", l}}
|
t <- Token{Error: &ParseError{"bad owner name", l}}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !Fqdn(h.Name) {
|
if !IsFqdn(h.Name) {
|
||||||
h.Name += origin
|
h.Name += origin
|
||||||
}
|
}
|
||||||
st = _EXPECT_OWNER_BL
|
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}}
|
t <- Token{Error: &ParseError{"Expecting $ORIGIN value, not this...", l}}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !Fqdn(l.token) {
|
if !IsFqdn(l.token) {
|
||||||
origin = l.token + origin // Append old origin if the new one isn't a fqdn
|
origin = l.token + origin // Append old origin if the new one isn't a fqdn
|
||||||
} else {
|
} else {
|
||||||
origin = l.token
|
origin = l.token
|
||||||
|
|
32
zscan_rr.go
32
zscan_rr.go
|
@ -123,10 +123,10 @@ func setNS(h RR_Header, c chan lex, o string) (RR, *ParseError) {
|
||||||
|
|
||||||
l := <-c
|
l := <-c
|
||||||
rr.Ns = l.token
|
rr.Ns = l.token
|
||||||
if ok, _ := IsDomainName(l.token); !ok {
|
if _, ok := IsDomainName(l.token); !ok {
|
||||||
return nil, &ParseError{"bad NS Ns", l}
|
return nil, &ParseError{"bad NS Ns", l}
|
||||||
}
|
}
|
||||||
if !Fqdn(rr.Ns) {
|
if !IsFqdn(rr.Ns) {
|
||||||
rr.Ns += o
|
rr.Ns += o
|
||||||
}
|
}
|
||||||
return rr, nil
|
return rr, nil
|
||||||
|
@ -145,10 +145,10 @@ func setMX(h RR_Header, c chan lex, o string) (RR, *ParseError) {
|
||||||
<-c // _BLANK
|
<-c // _BLANK
|
||||||
l = <-c // _STRING
|
l = <-c // _STRING
|
||||||
rr.Mx = l.token
|
rr.Mx = l.token
|
||||||
if ok, _ := IsDomainName(l.token); !ok {
|
if _, ok := IsDomainName(l.token); !ok {
|
||||||
return nil, &ParseError{"bad MX Mx", l}
|
return nil, &ParseError{"bad MX Mx", l}
|
||||||
}
|
}
|
||||||
if !Fqdn(rr.Mx) {
|
if !IsFqdn(rr.Mx) {
|
||||||
rr.Mx += o
|
rr.Mx += o
|
||||||
}
|
}
|
||||||
return rr, nil
|
return rr, nil
|
||||||
|
@ -160,10 +160,10 @@ func setCNAME(h RR_Header, c chan lex, o string) (RR, *ParseError) {
|
||||||
|
|
||||||
l := <-c
|
l := <-c
|
||||||
rr.Cname = l.token
|
rr.Cname = l.token
|
||||||
if ok, _ := IsDomainName(l.token); !ok {
|
if _, ok := IsDomainName(l.token); !ok {
|
||||||
return nil, &ParseError{"bad CNAME", l}
|
return nil, &ParseError{"bad CNAME", l}
|
||||||
}
|
}
|
||||||
if !Fqdn(rr.Cname) {
|
if !IsFqdn(rr.Cname) {
|
||||||
rr.Cname += o
|
rr.Cname += o
|
||||||
}
|
}
|
||||||
return rr, nil
|
return rr, nil
|
||||||
|
@ -176,19 +176,19 @@ func setSOA(h RR_Header, c chan lex, o string) (RR, *ParseError) {
|
||||||
l := <-c
|
l := <-c
|
||||||
rr.Ns = l.token
|
rr.Ns = l.token
|
||||||
<-c // _BLANK
|
<-c // _BLANK
|
||||||
if ok, _ := IsDomainName(l.token); !ok {
|
if _, ok := IsDomainName(l.token); !ok {
|
||||||
return nil, &ParseError{"bad SOA mname", l}
|
return nil, &ParseError{"bad SOA mname", l}
|
||||||
}
|
}
|
||||||
if !Fqdn(rr.Ns) {
|
if !IsFqdn(rr.Ns) {
|
||||||
rr.Ns += o
|
rr.Ns += o
|
||||||
}
|
}
|
||||||
|
|
||||||
l = <-c
|
l = <-c
|
||||||
rr.Mbox = l.token
|
rr.Mbox = l.token
|
||||||
if ok, _ := IsDomainName(l.token); !ok {
|
if _, ok := IsDomainName(l.token); !ok {
|
||||||
return nil, &ParseError{"bad SOA rname", l}
|
return nil, &ParseError{"bad SOA rname", l}
|
||||||
}
|
}
|
||||||
if !Fqdn(rr.Mbox) {
|
if !IsFqdn(rr.Mbox) {
|
||||||
rr.Mbox += o
|
rr.Mbox += o
|
||||||
}
|
}
|
||||||
<-c // _BLANK
|
<-c // _BLANK
|
||||||
|
@ -274,10 +274,10 @@ func setRRSIG(h RR_Header, c chan lex, o string) (RR, *ParseError) {
|
||||||
<-c // _BLANK
|
<-c // _BLANK
|
||||||
l = <-c
|
l = <-c
|
||||||
rr.SignerName = l.token
|
rr.SignerName = l.token
|
||||||
if ok, _ := IsDomainName(l.token); !ok {
|
if _, ok := IsDomainName(l.token); !ok {
|
||||||
return nil, &ParseError{"bad RRSIG signername", l}
|
return nil, &ParseError{"bad RRSIG signername", l}
|
||||||
}
|
}
|
||||||
if !Fqdn(rr.SignerName) {
|
if !IsFqdn(rr.SignerName) {
|
||||||
rr.SignerName += o
|
rr.SignerName += o
|
||||||
}
|
}
|
||||||
// Get the remaining data until we see a NEWLINE
|
// 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
|
l := <-c
|
||||||
rr.NextDomain = 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}
|
return nil, &ParseError{"bad NSEC nextdomain", l}
|
||||||
}
|
}
|
||||||
if !Fqdn(rr.NextDomain) {
|
if !IsFqdn(rr.NextDomain) {
|
||||||
rr.NextDomain += o
|
rr.NextDomain += o
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,10 +364,10 @@ func setNSEC3(h RR_Header, c chan lex, o string) (RR, *ParseError) {
|
||||||
l = <-c
|
l = <-c
|
||||||
rr.HashLength = uint8(len(l.token))
|
rr.HashLength = uint8(len(l.token))
|
||||||
rr.NextDomain = 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}
|
return nil, &ParseError{"bad NSEC nextdomain", l}
|
||||||
}
|
}
|
||||||
if !Fqdn(rr.NextDomain) {
|
if !IsFqdn(rr.NextDomain) {
|
||||||
rr.NextDomain += o
|
rr.NextDomain += o
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue