Update
This commit is contained in:
1 parent
3530afb854
commit
6903fcff27
2146 files changed
+112256
-190703
No files matched your search
+44
-5
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
// Package dnsname contains string functions for working with DNS names.
|
||||
@@ -20,6 +20,12 @@ const (
|
||||
// A FQDN is a fully-qualified DNS name or name suffix.
|
||||
type FQDN string
|
||||
|
||||
// ToFQDN returns s as an FQDN, with a trailing dot added if missing. The
|
||||
// empty string and "." both parse as ".".
|
||||
//
|
||||
// Names containing whitespace or control characters are rejected. See the
|
||||
// comment in the label loop below for why other characters are not
|
||||
// validated.
|
||||
func ToFQDN(s string) (FQDN, error) {
|
||||
if len(s) == 0 || s == "." {
|
||||
return FQDN("."), nil
|
||||
@@ -39,6 +45,18 @@ func ToFQDN(s string) (FQDN, error) {
|
||||
return "", vizerror.Errorf("%q is too long to be a DNS name", s)
|
||||
}
|
||||
|
||||
// DNS labels on the wire may contain any non-zero byte (see the note in
|
||||
// the label loop below about issue 2024), but names we accept from
|
||||
// control are also written verbatim into line-oriented OS configuration
|
||||
// files like resolv.conf and hosts, where a newline or carriage return
|
||||
// can inject whole new directives. Reject whitespace and control
|
||||
// characters so a malicious control server can't do that.
|
||||
for i := range len(s) {
|
||||
if c := s[i]; c <= ' ' || c == 0x7f {
|
||||
return "", vizerror.Errorf("%q contains invalid character %q", raw, c)
|
||||
}
|
||||
}
|
||||
|
||||
st := 0
|
||||
for i := range len(s) {
|
||||
if s[i] != '.' {
|
||||
@@ -94,14 +112,34 @@ func (f FQDN) Contains(other FQDN) bool {
|
||||
return strings.HasSuffix(other.WithTrailingDot(), cmp)
|
||||
}
|
||||
|
||||
// Parent returns the parent domain by stripping the first label.
|
||||
// For "foo.bar.baz.", it returns "bar.baz."
|
||||
// It returns an empty FQDN for root or single-label domains.
|
||||
func (f FQDN) Parent() FQDN {
|
||||
s := f.WithTrailingDot()
|
||||
_, rest, ok := strings.Cut(s, ".")
|
||||
if !ok || rest == "" {
|
||||
return ""
|
||||
}
|
||||
return FQDN(rest)
|
||||
}
|
||||
|
||||
// ValidLabel reports whether label is a valid DNS label. All errors are
|
||||
// [vizerror.Error].
|
||||
func ValidLabel(label string) error {
|
||||
return ValidLabelLike(label, maxLabelLength)
|
||||
}
|
||||
|
||||
// ValidLabelLike reports whether label contains DNS-valid characters
|
||||
// only, adheres to a given maximum length, and starts and ends with
|
||||
// a letter or number. For strict DNS-validity use [ValidLabel].
|
||||
// All errors are [vizerror.Error].
|
||||
func ValidLabelLike(label string, maxLen int) error {
|
||||
if len(label) == 0 {
|
||||
return vizerror.New("empty DNS label")
|
||||
}
|
||||
if len(label) > maxLabelLength {
|
||||
return vizerror.Errorf("%q is too long, max length is %d bytes", label, maxLabelLength)
|
||||
if len(label) > maxLen {
|
||||
return vizerror.Errorf("%q is too long, max length is %d bytes", label, maxLen)
|
||||
}
|
||||
if !isalphanum(label[0]) {
|
||||
return vizerror.Errorf("%q is not a valid DNS label: must start with a letter or number", label)
|
||||
@@ -109,7 +147,8 @@ func ValidLabel(label string) error {
|
||||
if !isalphanum(label[len(label)-1]) {
|
||||
return vizerror.Errorf("%q is not a valid DNS label: must end with a letter or number", label)
|
||||
}
|
||||
if len(label) < 2 {
|
||||
if len(label) <= 2 {
|
||||
// Return early because we've already checked start and end characters (the only 2) are alphanumeric.
|
||||
return nil
|
||||
}
|
||||
for i := 1; i < len(label)-1; i++ {
|
||||
@@ -222,7 +261,7 @@ func ValidHostname(hostname string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, label := range strings.Split(fqdn.WithoutTrailingDot(), ".") {
|
||||
for label := range strings.SplitSeq(fqdn.WithoutTrailingDot(), ".") {
|
||||
if err := ValidLabel(label); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user