zonefile

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Aug 22, 2026 License: AGPL-3.0 Imports: 7 Imported by: 0

Documentation

Overview

Package zonefile reads and writes zone data in the presentation format of RFC 1035 §5: what everybody calls a zonefile.

It is an import and export format and never a storage format (architecture invariant 5). Nothing here is on the query path and nothing here is what the server answers from: a file is read into records, the records go through the ordinary write path, and what the server serves is the database. Exporting runs the same trip backwards, so that moving off this server takes as long as moving onto it.

The lexing is the wire library's, for the reason ADR 0005 gives about RDATA: RFC 1035 §5 is line continuations, parentheses, comments, `@`, relative names, omitted owners, omitted classes, omitted TTLs and a presentation syntax per record type, and re-deriving it would produce something slightly worse than a parser that has been carrying production zones for a decade. What this package adds is the policy, which files we accept, what a zone has to contain to be one, and what a file becomes once it is read.

Index

Constants

View Source
const DefaultMaxRecords = 1_000_000

DefaultMaxRecords bounds what one file may turn into.

The bound is not about file size. `$GENERATE 1-16777215 $ PTR host-$` is thirty octets and expands to sixteen million records, so a limit on what arrives says nothing about what it becomes. A million is the zone size docs/decisions.md D12 designs for, so a file that produces more than that is past what this server is built to hold either way.

Variables

This section is empty.

Functions

func Write

func Write(w io.Writer, c *Content) error

Write renders a zone as an RFC 1035 §5 file.

The SOA comes first, as RFC 1035 §5.2 requires of the zone's first record, with the apex records after it and everything else in the canonical order of RFC 4034 §6.1: the same order the database lists them in, so exporting the same zone twice produces the same bytes.

Types

type Content

type Content struct {
	// Origin is the zone apex, taken from the owner name of the SOA. The file
	// says which zone it describes; the caller does not have to know.
	Origin zone.Name

	// SOA is the start of authority as the file gives it, serial included. An
	// import seeds from that serial rather than resetting it: see
	// docs/decisions.md D2.
	SOA zone.SOA

	// Records is everything else, with no zone identifier yet: the file does
	// not know which zone row it will land in, and inventing one here would be
	// a second place that mints identifiers.
	Records []zone.Record
}

Content is what a zonefile holds, once read.

The SOA is separate from the records because it is separate in the model: it is the zone's own settings rather than a record somebody edits, and its serial belongs to the journal (data model §4.1).

func Parse

func Parse(r io.Reader, opts Options) (*Content, error)

Parse reads a zonefile.

The zone it describes is whichever name its SOA sits at: a file carries that with it, so a caller does not have to be told twice and cannot be told inconsistently. Exactly one SOA is required: a file without one is a fragment rather than a zone, and a file with two does not say which.

type Options

type Options struct {
	// Origin is where relative names are resolved from, for a file that does
	// not set $ORIGIN itself. The root is used when it is not given, which is
	// almost certainly not what a file of relative names meant, so a file
	// like that is refused for having its records outside its own apex rather
	// than being imported into the wrong names.
	Origin zone.Name

	// DefaultTTL applies to a record that carries no TTL in a file that sets
	// no $TTL. Zero leaves it to the file, and a file that then omits one is
	// refused by the parser rather than given a number nobody chose.
	DefaultTTL zone.TTL

	// MaxRecords bounds how many records the file may produce. Zero takes
	// [DefaultMaxRecords]; a negative value removes the bound, which is for a
	// caller that has already bounded it some other way.
	MaxRecords int
}

Options configure a read.

Jump to

Keyboard shortcuts

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