wire

package
v1.8.0 Latest Latest
Warning

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

Go to latest
Published: Aug 18, 2026 License: MIT Imports: 4 Imported by: 0

Documentation

Overview

Package wire provides zero-allocation cursors over packed DNS messages.

Full Msg.Unpack materializes every record as a heap graph; most byte-path consumers need only the header, one section's skeleton, or a handful of fixed-position fields. These helpers read exactly the bytes a caller asks about and nothing else, so sectional inspection stays off the allocator entirely and a future partial decode (unpack just the answers, just the authority) can build on the same offsets.

Index

Constants

View Source
const (
	FlagRcodeMask = 0x000F
	FlagCD        = 1 << 4  // checking disabled
	FlagAD        = 1 << 5  // authenticated data (RFC 4035 §3.1.6)
	FlagRA        = 1 << 7  // recursion available
	FlagRD        = 1 << 8  // recursion desired
	FlagTC        = 1 << 9  // truncated
	FlagAA        = 1 << 10 // authoritative answer
	FlagOpcodeSh  = 11      // opcode occupies bits 11-14
	FlagOpcodeMsk = 0xF << FlagOpcodeSh
	FlagQR        = 1 << 15 // response
)

Flag bits within Header.Flags (RFC 1035 §4.1.1 layout).

View Source
const (
	// OPTFixedLen is the record's size before any option: the root owner
	// name, TYPE, CLASS (the requestor's UDP size), TTL (extended RCODE,
	// version and flags) and RDLENGTH.
	OPTFixedLen = 11
	// OPTOptionHdrLen is the per-option code and length prefix.
	OPTOptionHdrLen = 4
)

OPT record geometry (RFC 6891 §6.1.2).

View Source
const HeaderLen = 12

HeaderLen is the fixed DNS header size (RFC 1035 §4.1.1).

Variables

This section is empty.

Functions

func AppendName

func AppendName(dst, src []byte, off int) ([]byte, bool)

AppendName appends the uncompressed wire form of the (possibly compressed) name starting at off in src. ok is false on malformed input, a name exceeding 255 octets, or insufficient dst capacity — the append never grows dst's backing array, so a caller composing into a fixed lease can treat false as a clean refusal.

func AppendOPTHeader

func AppendOPTHeader(dst []byte, udpSize uint16, do bool) ([]byte, int)

AppendOPTHeader writes an OPT record's fixed part and returns the buffer along with the offset of its RDLENGTH field, which FinishOPT fills in once the options are known. Encoding the record directly avoids building a dns.OPT and its option objects only for the library to pack them — and, for options carried as hex text, avoids encoding bytes to hex just so the packer can decode them back.

func AppendOption

func AppendOption(dst []byte, code uint16, data []byte) []byte

AppendOption writes one EDNS0 option in wire form.

Options are written as the bytes the wire carries. Several of them — NSID and the cookies among them — are held in text form by the library's option types and hex-decoded during packing, so producing that text only to have it decoded back is pure waste on a hot path.

func AppendOptionEDE

func AppendOptionEDE(dst []byte, infoCode uint16, text string) []byte

AppendOptionEDE writes an RFC 8914 Extended DNS Error option — the two-byte info code followed by the extra text — without materializing a payload buffer or a library option object.

func AppendOptionString

func AppendOptionString(dst []byte, code uint16, data string) []byte

AppendOptionString is AppendOption for an option whose payload is already held as a string, appended without a byte-slice conversion.

func ApplyReply

func ApplyReply(body []byte, id uint16, opcode int, rd, cd bool)

ApplyReply stamps onto a packed response the header fields miekg's SetReply derives from the request, plus the cache's own reply shaping: the request ID, QR, the request opcode, the copied RD/CD bits, and a cleared AA (a cached answer is never authoritative). RA and TC are left as stored, matching the message path.

func ClearAD

func ClearAD(body []byte)

ClearAD clears the authenticated-data bit in place.

func FinishOPT

func FinishOPT(dst []byte, rdlenOff int) []byte

FinishOPT records the RDLENGTH of the options written since AppendOPTHeader returned rdlenOff.

func PackClone

func PackClone(msg *dns.Msg) ([]byte, error)

PackClone packs msg and returns an exact-size copy the caller owns. It is for the callsites that keep the bytes — a cache entry, an async queue — where a borrowed buffer must never travel. The library path is the fallback, trimmed to size the same way, so the caller sees one shape.

func SetAD

func SetAD(body []byte)

SetAD sets the authenticated-data bit.

func SetARCount

func SetARCount(body []byte, n uint16)

SetARCount stamps the additional-section count in place.

func SetRA

func SetRA(body []byte)

SetRA sets the recursion-available bit.

func SetRcode

func SetRcode(body []byte, rcode int)

SetRcode overwrites the header's 4-bit RCODE field.

func SetTTL

func SetTTL(body []byte, ttlOff int, ttl uint32)

SetTTL stamps a TTL value at a previously recorded offset.

func SkipName

func SkipName(body []byte, off int) int

SkipName advances past a (possibly compressed) domain name starting at off and returns the offset of the first byte after it, or -1 when the name is malformed or runs past the body.

func TryPack

func TryPack(msg *dns.Msg, consume func([]byte) error) (handled bool, err error)

TryPack encodes msg into wire format inside pooled storage and hands the bytes to consume. It exists because the library's Pack builds a compression dictionary and sizes an output array for every message it encodes; for a server that answers a query per packet, that was a map and an array per answer. Here both come from a pool, and the caller never touches either.

The contract, in order of importance:

  • The bytes handed to consume are exactly what dns.Msg.Pack would have produced. Where this cannot be guaranteed, TryPack does not try: it reports handled=false, no bytes are produced, and the caller uses the library path it was already using.
  • msg is not modified — not its header, not its records, not its OPT. This is deliberately stronger than the library, which writes the extended rcode into the caller's OPT and, through the public PackRR, the computed Rdlength into the caller's record headers. Both writes land in pooled shims here instead.
  • The slice given to consume is valid only for the duration of the call. A consumer that needs the bytes afterwards copies them; PackClone is that, prepackaged.

handled=true with a non-nil error is the consumer's error, reported after bytes may already have left the process — the caller must not fall back and write a second response.

Types

type Header struct {
	ID      uint16
	Flags   uint16
	QDCount uint16
	ANCount uint16
	NSCount uint16
	ARCount uint16
}

Header is the fixed-size DNS message header.

func ParseHeader

func ParseHeader(body []byte) (Header, bool)

ParseHeader reads the fixed header. ok is false when the body is short.

func (Header) AD

func (h Header) AD() bool

AD reports the authenticated-data bit.

func (Header) Opcode

func (h Header) Opcode() int

Opcode extracts the operation code from the flags word.

func (Header) QR

func (h Header) QR() bool

QR reports the response bit.

func (Header) Rcode

func (h Header) Rcode() int

Rcode extracts the response code from the flags word.

type Question

type Question struct {
	NameOff int // start of the owner name (== HeaderLen for the first)
	NameLen int // packed name length in bytes
	Qtype   uint16
	Qclass  uint16
	End     int // offset of the first byte after this question
}

Question is the skeleton of one question entry.

func ParseQuestion

func ParseQuestion(body []byte, off int) (Question, bool)

ParseQuestion reads the question at off. ok is false on malformed input.

type RR

type RR struct {
	NameOff int
	Type    uint16
	Class   uint16
	TTLOff  int
	RDLen   int
	End     int
}

RR is the skeleton of one resource record: fixed-field offsets without any rdata interpretation. TTLOff is the field byte-patch serving needs; End lets an iterator continue to the next record.

func ParseRR

func ParseRR(body []byte, off int) (RR, bool)

ParseRR reads the record skeleton at off. ok is false on malformed input.

Jump to

Keyboard shortcuts

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