dns

package module
v0.0.0-...-22c902c Latest Latest
Warning

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

Go to latest
Published: Aug 21, 2022 License: Apache-2.0 Imports: 8 Imported by: 0

README

Alternative (more granular) approach to a DNS library

Less is more.

WORK-IN-PROGRESS

“All these worlds are yours except Europa. Attempt no landing there.”

Eyeing what a more memory efficient DNS libary would look like, while retaining the ease of use miekg/dns has. Everything here can, and will, change. If you have opinions open an issue.

DNS compression is always done. Making this optional and a user knob is a mistake.

Current Status

  • Some very basic RRs are working, the rest is trivial, but some go generate would help here.
  • EDNS0 is implemented.
  • Unknown RRs are implemented.
  • Unknown EDNS0 options (not an official thing) are implemented.
  • Message creating and parsing works with default compression.

Memory Model

A message is the central buffer, extracting RRs and walking the message to get RRs will copy the data out of the message and into the RR. These new buffers can either be pre-allocated (and will be resized by this package), or allocated anew. After you got all the data from a message its buffer can be reused/discarded.

Creating a new message works opposite. Bytes from RRs are copied into the message. Once the message is fully created the RR's buffer maybe reused/discarded.

API

As everything in DNS looks like an RR, the choice was made to make everything an RR. Notably the question section of the DNS message is also an RR (albeit lacking rdata and a TTL), but if you extract a question "RR" you get an RR.

EDNS0's RR: the OPT RR's option also mimics the RR interface as much as possible. In some sense the options in the OPT record are mini RRs.

It is now possible to access the specific rdata elements from an RR and the default String() functions now only return the text representation of the rdata. This should give much better options at storing parts of an RR.

All functions/methods allow you to give (an) optional buffer that you control.

Msg is the central struct. It contains the RRs either from the wire or when being build up. Building a Msg needs to happen in-order, as a DNS message can only be traversed from the start. The buffer containing the wire data is a public member, so the caller can have complete control.

Reading from a Msg can be done via any section in any order, from within a section it needs be in-order. Writing a Msg can only be done in the order: Qd, An, Ns, and Ar, where empty sections can be skipped.

RRs in a Msg contain compression pointers, anything lifted out of a Msg will not contain compression pointers. I.e. a user should not care about this.

Methods on a Msg are:

  • RR(s Section) RR which returns the next RR from the section or nil when none found. As said above there is no different method for the question section.
  • SetRR(s Section, r RR) will add an RR to the specific section, again the order is important, so first question section Qd, and then answer An, authority Ns and lastly additional Ar.
  • RRs(s Section) []RR returns all RRs from a specific section.
  • SetRRs(s Section, rs []RR) sets an entire section.

All RR types are in upper-case, except 'Unknown' as that is the odd one out. UnknownEDNS0 also exist.

All public APIs use int, internally most things are uint16.

Examples
Stripping OPT RR and Forwarding Message

Take for example a "forwarder", or "resolver", such software takes in coming request and resolves it, then returns the response. One of the first steps undertaking by it is checking what kind of EDNS0 option are set. This means finding the OPT RR in the additional section, which should be (in case of TSIG it might not be) the last RR in the message. Then that (or those) RR(s) need to be stripped as EDNS0 (and TSIG) are hop-by-hop. And after that a new OPT RR will be added and the message will be forwarded (with a new message ID). In this use-case it would be nice to re-use as much of the buffer we already have. The following API is implemented for this:

pos := 0
err := m.Walk(WalkBackward, func(s Section, rr RR, i int) error {
    if s == Ar && RRToType(rr) == TypeOPT {
        pos = i
        return errors.New("found opt RR")
    }
    return nil
})
if err != nil {
    rrs, err := m.Strip(pos + 1)
    opt := rrs[0]
}
Questionable things
  • Doing [2]byte{x, y} instead of a uint16 for Class and Type?
  • Needing helper function in the dnswire package to convert from an to rdata types.
  • Msg can only be written in the correct order. Technically we should be able to insert RRs, but this requires updating compression pointers which need to be found?
  • The Header doesn't contain the type, as this is encoded in the Go Type of the RR, so printing them as strings looks a bit weird (compared to dig).
  • Question "RR" needs special casing because it obvs isn't a real RR either.
  • Len() for RRs and Len() for Options do different things...
TODO
  • From string conversion, also need for scanning zone files.

  • Unprintables escaping \DDD in text and domain names.

  • TCP writes, with message length - how to optimize and don't have 2 syscalls? Leave to user? append(len, oldbuf)

  • Label manipulation functions still need to be defined, and seeing what other things might be helpful without bloating the package. Name.Next() is a first of these.

  • Maybe this should serve as a lower level package, dnsrr and build a nicer API on top? I.e should server and client be here or in a dnsnet pkg?

  • Decide where to use int and where to use uint16. Uint16 is more natural as length and index thingy, but int is more used in std go stuff (ie. len returns an int).

  • Length check on domain names (<256) octect, 63 label length.

  • Buffer length checks when unpacking and packing.

  • Use Octets as a name every where instead of bytes - give that old school feel?

  • Make Header also implement the RR interface, so it's also an RR? This would simplify the Msg creation, as you can just take a Bytes() from the header as well. Bytes is a bad name.

  • Make RRSet a first class citizen, i.e get those from a message, mem friendly struct?

  • Implement compression for CNAME, MX, NS, PTR, and SOA.

  • unpackXXXX need to take uint16, instead of int.

  • strconv.Name, and strconv.IPv4 etc? Should we add these? strconv.Type(t string) Type ??

  • [2]byte everywhere is annoying, might change to uin16, uint32, but 48 bits are (TSIG) are crap again...

Documentation

Overview

Package dns implements a fast and natural interface to the Domain Name System.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	CodeNone   = Code{0, 0}
	CodeNSID   = Code{0, 3}
	CodeCookie = Code{0, 10}
)

Supported EDNS0 Option Codes.

View Source
var (
	// Valid Classes.
	IN   = Class{0, 1}
	NONE = Class{0, 254}
	ANY  = Class{0, 255}

	// Supported RR Types.
	TypeNone  = Type{0, 0}
	TypeA     = Type{0, 1}
	TypeNS    = Type{0, 2}
	TypeCNAME = Type{0, 5}
	TypeSOA   = Type{0, 6}
	TypePTR   = Type{0, 12}
	TypeMX    = Type{0, 15}
	TypeOPT   = Type{0, 41}
)
View Source
var ClassToString = map[Class]string{
	ANY:  "ANY",
	IN:   "IN",
	NONE: "NONE",
}

ClassToString maps Classes to strings.

View Source
var IDFunc = id

IDFunc returns a 16-bit random number that is used as the message's ID. This can be overriden if so desired.

View Source
var OpcodeToString = map[Opcode]string{
	OpcodeIQuery: "IQUERY",
	OpcodeNotify: "NOTIFY",
	OpcodeQuery:  "QUERY",
	OpcodeStatus: "STATUS",
	OpcodeUpdate: "UPDATE",
}

OpcodeToString maps Opcodes to strings.

View Source
var RcodeToString = map[Rcode]string{
	RcodeFormErr:  "FORMERR",
	RcodeNXDomain: "NXDOMAIN",
	RcodeNoError:  "NOERROR",
	RcodeNotImp:   "NOTIMP",
	RcodeRefused:  "REFUSED",
	RcodeServFail: "SERVFAIL",
}

RcodeToString maps Rcodes to strings.

View Source
var StringToClass = reverseClass(ClassToString)

StringToClass maps strings to Classes.

View Source
var StringToOpcode = reverseOpcode(OpcodeToString)

StringToOpcode maps strings to Opcodes.

View Source
var StringToRcode = reverseRcode(RcodeToString)

StringToRcode maps strings to Rcodes.

View Source
var StringToType = reverseType(TypeToString)

StringToType maps strings to Types.

View Source
var TypeToRR = map[Type]func() RR{
	TypeA:     func() RR { return new(A) },
	TypeCNAME: func() RR { return new(CNAME) },
	TypeMX:    func() RR { return new(MX) },
	TypeNS:    func() RR { return new(NS) },
	TypeOPT:   func() RR { return new(OPT) },
	TypePTR:   func() RR { return new(PTR) },
	TypeSOA:   func() RR { return new(SOA) },
}

TypeToRR is a mapping from Type to a function that returns the type.

View Source
var TypeToString = map[Type]string{
	TypeA:     "A",
	TypeCNAME: "CNAME",
	TypeMX:    "MX",
	TypeNS:    "NS",
	TypeOPT:   "OPT",
	TypePTR:   "PTR",
	TypeSOA:   "SOA",
}

TypeToString maps Types to strings.

Functions

func NewIPv4

func NewIPv4(v net.IP, buf ...[]byte) [4]byte

NewIPv4 returns a 4 byte buffer from v. If buf is not nil the 4 bytes are written into it.

Types

type A

type A struct {
	Header
	A [4]byte `dns:"-string"`
}

A RR. See RFC 1035.

func (*A) Data

func (rr *A) Data(i int) []byte

func (*A) Hdr

func (rr *A) Hdr() *Header

func (*A) Len

func (rr *A) Len() int

func (*A) String

func (rr *A) String() string

func (*A) Write

func (rr *A) Write(msg []byte, offset, n int) (err error)

type CNAME

type CNAME struct {
	Header
	Target Name
}

CNAME RR. See RFC 1035.

func (*CNAME) Data

func (rr *CNAME) Data(i int) []byte

func (*CNAME) Hdr

func (rr *CNAME) Hdr() *Header

func (*CNAME) Len

func (rr *CNAME) Len() int

func (*CNAME) String

func (rr *CNAME) String() string

func (*CNAME) Write

func (rr *CNAME) Write(msg []byte, offset, n int) (err error)
type COOKIE struct {
	Cookie []byte // Cookie is a hex encoded string.
}

Cookie Option.

func (*COOKIE) Data

func (o *COOKIE) Data() []byte

func (*COOKIE) Len

func (o *COOKIE) Len() int

func (*COOKIE) String

func (o *COOKIE) String() string

func (*COOKIE) Write

func (o *COOKIE) Write(buf []byte) error

type Class

type Class [2]byte // Class is the class of the RR. Usually every RR has IN as its class.

func (Class) String

func (c Class) String() string

String returns the string representation for Class c, unknown opcodes return CLASS<num>.

type Code

type Code [2]byte

Code represents the 2 byte option code.

func OptionCode

func OptionCode(e Option) Code

OptionCode returns the option code of the Option.

type Flag

type Flag uint16

Flag is a (boolean) message header flag.

const (
	QR Flag = 1 << 15 // Query Response
	AA Flag = 1 << 10 // Authoritative Answer
	TC Flag = 1 << 9  // TrunCated
	RD Flag = 1 << 8  // Recursion Desired
	RA Flag = 1 << 7  // Recussion Available
	Z  Flag = 1 << 6  // Zero bits
	CD Flag = 1 << 4  // Checking Disabled
)

These are the flags currently defined for a DNS message's header.

func (Flag) String

func (f Flag) String() string
type Header struct {
	Name // Owner name of the Resource Record.
	// Type is implicit and retrieved via the RR's Go type.
	Class // Class of the Resource Record.
	TTL   // Time to Live of the Resource Record.
}

Header is the header each RR has.

func (*Header) OPTString

func (h *Header) OPTString(opt *OPT) string

StringOPT returns the header as needed for rendering an OPT header.

func (*Header) QdString

func (h *Header) QdString(rr RR) string

QdString returns the header as needed for rendering an question section.

func (*Header) String

func (h *Header) String() string

type MX

type MX struct {
	Header
	Preference [2]byte
	Exchange   Name
}

MX RR. See RFC 1035.

func (*MX) Data

func (rr *MX) Data(i int) []byte

func (*MX) Hdr

func (rr *MX) Hdr() *Header

func (*MX) Len

func (rr *MX) Len() int

func (*MX) String

func (rr *MX) String() string

func (*MX) Write

func (rr *MX) Write(msg []byte, offset, n int) (err error)

type Msg

type Msg struct {
	Buf []byte // Buf is the message as read from the wire or as created.
	// contains filtered or unexported fields
}

Msg is a DNS message which is used in the query and the response. It's defined as follows:

+---------------------+
|    Message Header   |
+---------------------+
|       Question      | the question for the name server, [Qd].
+---------------------+
|        Answer       | RRs answering the question, [An].
+---------------------+
|      Authority      | RRs pointing toward an authority, [Ns].
+---------------------+
|      Additional     | RRs holding additional information, [Ar].
+---------------------+

A Msg allows RRs to be added (in order) or retrieved (in order per section, but sections can accessed in any order).

Even though the protocol allows multiple questions, in practice only 1 is allowed, this package enforces that convention. After setting any RR, the message's buffer may be written to the wire as it will contain a valid DNS message. In this package the question section's RR is handled as a normal RR, just without any rdata - as is also done in dynamic updates (RFC 2136).

The message header is defined as follows:

                                1  1  1  1  1  1
  0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                      ID                       |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|QR|   Opcode  |AA|TC|RD|RA|Z |AD|CD|   RCODE   |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    QDCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    ANCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    NSCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    ARCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

If the buffer in Msg is too small it will be resized while creating a message. Domain names that can be compressed will be compressed. If you assign a new byte slice to Buf, [Reset()] must be called to reset all internal counters and the compression map.

func NewMsg

func NewMsg(buf ...[]byte) *Msg

NewMsg returns a pointer to a new Msg. Optionally a buffer can be given here, NewMsg will not allocate a buffer on behalf of the caller, it will enlarge a buffer when the need arises. After assigning a new buffer to a Msg you must call [Reset].

func (*Msg) Count

func (m *Msg) Count(s Section) uint16

Count returns the section count for section s.

func (*Msg) Flag

func (m *Msg) Flag(f Flag) bool

Flag returns the value of flag f.

func (*Msg) GoString

func (m *Msg) GoString() string

func (*Msg) ID

func (m *Msg) ID() uint16

ID returns the message's ID.

func (*Msg) Len

func (m *Msg) Len() int

Len returns the length of the buffer in m that has been written thus far.

func (*Msg) Opcode

func (m *Msg) Opcode() Opcode

Opcode returns the Operation Code from the message m.

func (*Msg) RR

func (m *Msg) RR(s Section) (RR, error)

RR returns the next RR from the specified section. If none are found, nil is returned. If there is an error, a partial RR may be returned. When first called a message will be walked to find the indices of the sections.

func (*Msg) RRs

func (m *Msg) RRs(s Section) ([]RR, error)

RRs returns all the RRs from the section s.

Example
m := &Msg{Buf: tmpbuf(reply)}

answer, err := m.RRs(An)
if err != nil {
	return
}
for _, rr := range answer {
	fmt.Printf("%s %s\n", rr.Hdr(), rr)
}
Output:

miek.nl. 	  900 IN MX	5 alt2.aspmx.l.google.com.
miek.nl. 	  900 IN MX	1 aspmx.l.google.com.
miek.nl. 	  900 IN MX	10 aspmx2.googlemail.com.
miek.nl. 	  900 IN MX	10 aspmx3.googlemail.com.
miek.nl. 	  900 IN MX	5 alt1.aspmx.l.google.com.

func (*Msg) Rcode

func (m *Msg) Rcode() Rcode

Rcode returns the return code from the message m.

func (*Msg) Reset

func (m *Msg) Reset()

Reset resets all internal counters in m. This must be called after a new buffer is assigned to m.

func (*Msg) SetCount

func (m *Msg) SetCount(s Section, i uint16)

SetCount sets the section counter for s to i.

func (*Msg) SetFlag

func (m *Msg) SetFlag(f Flag, v ...bool)

SetFlag sets the flag f to value v. If v is not given 'true' is assumed.

func (*Msg) SetID

func (m *Msg) SetID(i ...uint16)

SetID sets the message to i. If i is not given, IDFunc is used to generate one.

func (*Msg) SetOpcode

func (m *Msg) SetOpcode(o Opcode)

Opcode sets the Operation Code in the message m.

func (*Msg) SetRR

func (m *Msg) SetRR(s Section, rr RR) error

SetRR adds rr's wireformat to the message m in the specified section. Any RR can be used to set the question section; it will then just use the name, type and class and ignore the

func (*Msg) SetRRs

func (m *Msg) SetRRs(s Section, rrs []RR) error

SetRR adds each rr's wireformat n rrs to the message m in the specified section.

func (*Msg) SetRcode

func (m *Msg) SetRcode(r Rcode)

Rcode sets the Return Code in the message m.

func (*Msg) String

func (m *Msg) String() string

String returns the text representation of the message m. Note this method _parses_ the message and extracts the RRs for printing, this makes it an expensive method. It can also error, in that case the empty string is returned. Mostly useful for debugging.

Example
m := &Msg{Buf: tmpbuf(reply)}

fmt.Printf("%s\n", m)
/*
   Ouput: ;; MESSAGE HEADER: opcode: QUERY, status: NOERROR, id: 59761
   ;; flags: qr rd ra ad; QUESTION 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 1
   ;; QUESTION SECTION:
   miek.nl. IN MX

   ;; ANSWER SECTION:
   miek.nl. 	  900 IN	MX	5 alt2.aspmx.l.google.com.
   miek.nl. 	  900 IN	MX	1 aspmx.l.google.com.
   miek.nl. 	  900 IN	MX	10 aspmx2.googlemail.com.
   miek.nl. 	  900 IN	MX	10 aspmx3.googlemail.com.
   miek.nl. 	  900 IN	MX	5 alt1.aspmx.l.google.com.

   ;; ADDITIONAL SECTION:
   ;; EDNS: version: 0, flags:; udp: 512
*/ udp: 512
*/
Output:

func (*Msg) Strip

func (m *Msg) Strip(n int) ([]RR, error)

Strip strips the last n RRs from the message. The stripped RRs are returned, the section counters are adjusted as necessary. Strips disregards any section boundaries. After a call to Strip any reads from m start from the beginning again. The buffer in m is not downsized. Compression pointers are NOT updated.

func (*Msg) Walk

func (m *Msg) Walk(d WalkDirection, fn WalkFunc) (err error)

Walk walks the section s in the message m in the direction of d. Each rr is filtered by fn. If WalkFunc returns an error the walk is stopped. Note due to DNS messages are structed an WalkBackward requires to walk forward and then backwards.

type NS

type NS struct {
	Header
	Target Name
}

NS RR. See RFC 1035.

func (*NS) Data

func (rr *NS) Data(i int) []byte

func (*NS) Hdr

func (rr *NS) Hdr() *Header

func (*NS) Len

func (rr *NS) Len() int

func (*NS) String

func (rr *NS) String() string

func (*NS) Write

func (rr *NS) Write(msg []byte, offset, n int) (err error)

type NSID

type NSID struct {
	ID []byte // ID is a hex encoded string.
}

NSID Option.

func (*NSID) Data

func (o *NSID) Data() []byte

func (*NSID) Len

func (o *NSID) Len() int

func (*NSID) String

func (o *NSID) String() string

func (*NSID) Write

func (o *NSID) Write(buf []byte) error

type Name

type Name []byte // Name is the owner name of the RR.

func NewName

func NewName(s string, buf ...[]byte) Name

NewName returns a name from s. If s is not a valid name nil is returned. If buf is not nil the name is written into it.

func (Name) GoString

func (n Name) GoString() string

func (Name) Next

func (n Name) Next(i int) (int, bool)

Next returns the index of the next label of n. The returned bool indicates the end as been reached. The last index returned is the positon of the root "label".

func (Name) String

func (n Name) String() string

type OPT

type OPT struct {
	Header
	Options []Option `dns:"len,-data,-string,-write"`
}

OPT is the EDNS0 RR appended to messages to convey extra (meta) information. See RFC 6891. Each option is encoded as:

            +0 (MSB)                            +1 (LSB)
   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
0: |                          OPTION-CODE                          |
   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
2: |                         OPTION-LENGTH                         |
   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
4: |                                                               |
   /                          OPTION-DATA                          /
   /                                                               /
   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

func NewOPT

func NewOPT() *OPT

NewOPT returns a pointer to a new OPT that has the correct properties to be used for EDNS0 options.

func (*OPT) Data

func (rr *OPT) Data(i int) []byte

func (*OPT) Do

func (rr *OPT) Do() bool

func (*OPT) ExtendedRcode

func (rr *OPT) ExtendedRcode() uint8

ExtendedRcode returns the extended Rcode.

func (*OPT) Hdr

func (rr *OPT) Hdr() *Header

func (*OPT) Len

func (rr *OPT) Len() int

func (*OPT) SetDo

func (rr *OPT) SetDo(do ...bool)

SetDo sets the DO (DNSSEC OK) bit to the (optional) value 'do'.

func (*OPT) SetSize

func (rr *OPT) SetSize(s uint16)

func (*OPT) Size

func (rr *OPT) Size() uint16

Size returns the UDP size set in the OPT RR.

func (*OPT) String

func (rr *OPT) String() string

func (*OPT) Version

func (rr *OPT) Version() uint8

func (*OPT) Write

func (rr *OPT) Write(msg []byte, offset, n int) error

type Opcode

type Opcode uint8

Opcode is the operation code for a message.

const (
	OpcodeQuery  Opcode = 0
	OpcodeIQuery Opcode = 1
	OpcodeStatus Opcode = 2
	OpcodeNotify Opcode = 3
	OpcodeUpdate Opcode = 4
)

The defined Operation Codes.

func (Opcode) String

func (o Opcode) String() string

String returns the string representation for Opcode o, unknown opcodes return OPCODE<num>.

type Option

type Option interface {
	// Len returns the option's value length. This is excluding the option code and length (which is always
	// 4 octets): len(o.Data()) = o.Len() + 4.
	Len() int

	// Data returns the option's values. The buffer returned is in wire format, all options require option
	// code and length, this is prepended in the buffer.
	Data() []byte

	// String returns the string representation of the EDNS0 option.
	String() string

	// Write writes the rdata encoded in buf into the EDNS0 option.
	Write(buf []byte) error
}

An Option represents an OPT RR rdata value. Basic usage for adding an option to an OPT RR:

opt := dns.NewOPT()
nsid := &dns.NSID{ID: []byte("AA")}
opt.Options = []Option{nsid}

type PTR

type PTR struct {
	Header
	Target Name
}

PTR RR. See RFC 1035.

func (*PTR) Data

func (rr *PTR) Data(i int) []byte

func (*PTR) Hdr

func (rr *PTR) Hdr() *Header

func (*PTR) Len

func (rr *PTR) Len() int

func (*PTR) String

func (rr *PTR) String() string

func (*PTR) Write

func (rr *PTR) Write(msg []byte, offset, n int) (err error)

type RR

type RR interface {
	// Hdr returns a pointer to the header of the RR.
	Hdr() *Header
	// Len returns the number of rdata elements the RR has. For RRs with a dynamic number of elements (i.e.
	// OPT, and others), this is not a constant number.
	Len() int
	// Data returns the rdata at position i (zero based). If there is no data at that position nil is
	// returned. The buffer returned is in wire format, i.e. if some data requires a length, that length is
	// prepended to the buffer.
	Data(i int) []byte
	// FromString transforms the string s in the the wire data suitable for the rdata at position i.
	// FromString(i int, s string) []byte
	// String returns the string representation of the rdata(!) only.
	String() string
	// Write writes the rdata encoded in msg starting at index offset and length n to the RR. Some rdata
	// needs access to the message's data msg to resolve compression pointers. If msg buffer is too small to
	// fit the data it is enlarged.
	Write(msg []byte, offset, n int) error
}

RR defines a Resource Record. Note that even the special RR in the question section is handled as a normal Resource Record (i.e with a zero TTL and no rdata).

type Rcode

type Rcode uint16

Rcode is the return (status) code for a message.

const (
	RcodeNoError  Rcode = 0
	RcodeFormErr  Rcode = 1
	RcodeServFail Rcode = 2
	RcodeNXDomain Rcode = 3
	RcodeNotImp   Rcode = 4
	RcodeRefused  Rcode = 5
)

The defined Return Codes. Note about extended rcodes. TODO

func (Rcode) String

func (r Rcode) String() string

String returns the string representation for Rcode r, unknown Rcodes return RCODE<num>.

type SOA

type SOA struct {
	Header
	Ns      Name
	Mbox    Name
	Serial  [4]byte
	Refresh [4]byte
	Retry   [4]byte
	Expire  [4]byte
	MinTTL  [4]byte
}

SOA RR. See RFC 1035.

func (*SOA) Data

func (rr *SOA) Data(i int) []byte

func (*SOA) Hdr

func (rr *SOA) Hdr() *Header

func (*SOA) Len

func (rr *SOA) Len() int

func (*SOA) String

func (rr *SOA) String() string

func (*SOA) Write

func (rr *SOA) Write(msg []byte, offset, n int) (err error)

type Section

type Section uint8

Section signifies a message's section. Four sections are defined (in order): Qd, An, Ns, and Ar.

const (
	Qd Section = iota // Query Domain/Data (count)
	An                // Answer (count)
	Ns                // Ns (count)
	Ar                // Additional Resource (count)
)

These are the sections in a Msg.

func (Section) String

func (s Section) String() string

type TTL

type TTL [4]byte // TTL is the time to live of the RR.

func NewTTL

func NewTTL(t uint32, buf ...[]byte) TTL

NewTTL returns a TTL from t. If buf is not nil the TTL is written into it.

func (TTL) String

func (t TTL) String() string

type Type

type Type [2]byte // Type is the Type of an RR. An RR in this package is implicitly typed via it's Go type.

func RRToType

func RRToType(rr RR) Type

RRToType returns the type of the RR.

func (Type) String

func (t Type) String() string

String returns the string representation for Type t, unknown Types return TYPE<num>.

type Unknown

type Unknown struct {
	Header
	Type           // Type holds the type number of the unknown type we're holding.
	Unknown []byte // Data is as-is.
}

Unknown represents an unknown/generic RR. See RFC 3597.

func (*Unknown) Data

func (rr *Unknown) Data(i int) []byte

func (*Unknown) Hdr

func (rr *Unknown) Hdr() *Header

func (*Unknown) Len

func (rr *Unknown) Len() int

func (*Unknown) String

func (rr *Unknown) String() string

func (*Unknown) Write

func (rr *Unknown) Write(msg []byte, offset, n int) error

type UnknownEDNS0

type UnknownEDNS0 struct {
	Code           // Code holds the option code number of the unknown option code we're holding.
	Unknown []byte // Data as-is.
}

UnknownEDNS0 is an unknown EDNS0 Option. Similar in style to RFC 3597 handling.

func (*UnknownEDNS0) Data

func (o *UnknownEDNS0) Data() []byte

func (*UnknownEDNS0) Len

func (o *UnknownEDNS0) Len() int

func (*UnknownEDNS0) String

func (o *UnknownEDNS0) String() string

func (*UnknownEDNS0) Write

func (o *UnknownEDNS0) Write(buf []byte) error

type WalkDirection

type WalkDirection int

WalkDirection tells in what order to walk the message.

const (
	WalkForward WalkDirection = iota
	WalkBackward
)

type WalkFunc

type WalkFunc func(s Section, rr RR, i int) error

WalkFunc is the type of the function called by Walk to visit each RR. This RR will only have its header populated, no no rdata is unpacked. The integer is the index of this RR in its section.

type WireError

type WireError struct {
	// contains filtered or unexported fields
}

WireError is an error that is returned when packing or unpacking RRs fails.

func (*WireError) Error

func (w *WireError) Error() string

Directories

Path Synopsis
cmd
q
The dnswire package contains functions to write to wire format.
The dnswire package contains functions to write to wire format.
internal

Jump to

Keyboard shortcuts

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