dnsname

package
v1.8.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 1, 2026 License: MIT Imports: 2 Imported by: 0

Documentation

Overview

Package dnsname walks domain-name labels without allocating.

The library answers every label question by materializing it: Split builds an index slice, SplitDomainName a string slice, and CompareDomainName two index slices — per call, for answers that are a handful of comparisons. In the field the two of them were 4.3% of every object the resolver allocated. The functions here give the same answers out of a single forward walk, using the library's own NextLabel for boundary and escape handling, so there is no second implementation of `\.` to get wrong.

Index

Constants

View Source
const MaxLabels = 127

MaxLabels bounds the label count of any legal wire name: every label needs a length byte plus one octet inside the 255-octet wire bound.

View Source
const MaxPresentationLength = 61*4 + 1 + 63*4 + 1 + 63*4 + 1 + 63*4 + 1

MaxPresentationLength bounds the presentation form of any legal wire name: every octet escaping to \DDD, plus label separators. Callers size stack buffers with it.

Variables

This section is empty.

Functions

func AppendCanonicalLabels

func AppendCanonicalLabels(dst, wire []byte, offs []int) ([]byte, int, bool)

AppendCanonicalLabels appends the canonical spelling — the presentation form with ASCII A–Z lowered and the trailing dot kept, dns.CanonicalName's answer — and records where each label starts inside the appended region. offs needs capacity MaxLabels; the returned count says how many entries were filled, and its contents are undefined on refusal. Suffix matching against canonical zone keys then indexes a map with canon[offs[i]:] without ever building a string — a recipe that assumes an empty dst, since the offsets are relative to the appended region, not the slice.

func AppendFoldedKey

func AppendFoldedKey(dst, wire []byte) ([]byte, bool)

AppendFoldedKey appends the lookup-key form: the presentation form with ASCII A–Z lowered and no trailing dot (the root name comes back empty). This is the spelling hostsfile keys its database with and domain metrics tracks, so a stack-buffered key indexes those maps with zero allocation.

func AppendPresentation

func AppendPresentation(dst, wire []byte) ([]byte, bool)

AppendPresentation appends the presentation form of an uncompressed wire-form name to dst — byte-identical to what dns.UnpackDomainName returns for the same bytes, trailing dot included, case preserved.

func CanonicalCompare

func CanonicalCompare(a, b string) int

CanonicalCompare orders a and b per RFC 4034 §6.3: the canonical DNS name order — labels compared right to left as the octets they decode to, ASCII-folded, with the name that runs out of labels first sorting first. It is the ordering every NSEC coverage proof stands on.

The octets, not the spelling. A presentation label is an encoding — `\065` is the octet 0x41, the same label as `a`; `\.` inside a label is the octet 0x2E, which sorts before `0` — and the comparison this replaces ordered the escape text instead, so wire-equal names compared unequal and names around the escapes could invert. Every escape is decoded as it is read — exactly as the library's packer decodes it, wrap quirk included (see decodeOctet) — and nothing is materialized. A dangling backslash, which no valid name contains, decodes as a literal one, keeping the order total for inputs only a hand can construct.

The fold is ASCII, which is what the RFC's canonical form specifies. (The old implementation folded through strings.ToLower, whose non-ASCII case mappings have no business in DNS names.)

Rooted and unrooted spellings compare equal: labels are read without their separators, so the trailing root dot contributes nothing.

The walk is forward, in label lockstep after aligning the starts, and the verdict is the rightmost pair that differed — right-to-left order without offset arrays, so the frame stays flat instead of carrying two of them.

func CompareSuffix

func CompareSuffix(a, b string) int

CompareSuffix returns how many labels a and b share, counted from the right and stopping at the first inequality — dns.CompareDomainName's answer without its two index slices.

The library's exact comparison is preserved: ASCII case folding only, the final label read to the end of the string (so a rooted and an unrooted spelling of the same name do not match on it), and every other label read through its separating dot.

func Sub

func Sub(zone, name string) bool

Sub reports whether name sits at or below zone — dns.IsSubDomain's answer, which is CompareSuffix covering every label of the zone.

func Suffixes

func Suffixes(name string) iter.Seq[int]

Suffixes yields the start offset of every label in name, in order — dns.Split's answer as an iteration instead of a slice. The root name yields nothing, exactly as Split returns nil for it.

func WireLabelCount

func WireLabelCount(wire []byte) (int, bool)

WireLabelCount returns the number of labels in an uncompressed wire-form name — dns.CountLabel's answer without the string. The root name has zero.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL