435c0d9fc8
This PR switches the Nomad repository from using govendor to Go modules for managing dependencies. Aspects of the Nomad workflow remain pretty much the same. The usual Makefile targets should continue to work as they always did. The API submodule simply defers to the parent Nomad version on the repository, keeping the semantics of API versioning that currently exists.
135 lines
3.7 KiB
Go
135 lines
3.7 KiB
Go
package dns
|
|
|
|
import "strconv"
|
|
|
|
const (
|
|
year68 = 1 << 31 // For RFC1982 (Serial Arithmetic) calculations in 32 bits.
|
|
defaultTtl = 3600 // Default internal TTL.
|
|
|
|
// DefaultMsgSize is the standard default for messages larger than 512 bytes.
|
|
DefaultMsgSize = 4096
|
|
// MinMsgSize is the minimal size of a DNS packet.
|
|
MinMsgSize = 512
|
|
// MaxMsgSize is the largest possible DNS packet.
|
|
MaxMsgSize = 65535
|
|
)
|
|
|
|
// Error represents a DNS error.
|
|
type Error struct{ err string }
|
|
|
|
func (e *Error) Error() string {
|
|
if e == nil {
|
|
return "dns: <nil>"
|
|
}
|
|
return "dns: " + e.err
|
|
}
|
|
|
|
// An RR represents a resource record.
|
|
type RR interface {
|
|
// Header returns the header of an resource record. The header contains
|
|
// everything up to the rdata.
|
|
Header() *RR_Header
|
|
// String returns the text representation of the resource record.
|
|
String() string
|
|
|
|
// copy returns a copy of the RR
|
|
copy() RR
|
|
|
|
// len returns the length (in octets) of the compressed or uncompressed RR in wire format.
|
|
//
|
|
// If compression is nil, the uncompressed size will be returned, otherwise the compressed
|
|
// size will be returned and domain names will be added to the map for future compression.
|
|
len(off int, compression map[string]struct{}) int
|
|
|
|
// pack packs the records RDATA into wire format. The header will
|
|
// already have been packed into msg.
|
|
pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error)
|
|
|
|
// unpack unpacks an RR from wire format.
|
|
//
|
|
// This will only be called on a new and empty RR type with only the header populated. It
|
|
// will only be called if the record's RDATA is non-empty.
|
|
unpack(msg []byte, off int) (off1 int, err error)
|
|
|
|
// parse parses an RR from zone file format.
|
|
//
|
|
// This will only be called on a new and empty RR type with only the header populated.
|
|
parse(c *zlexer, origin string) *ParseError
|
|
|
|
// isDuplicate returns whether the two RRs are duplicates.
|
|
isDuplicate(r2 RR) bool
|
|
}
|
|
|
|
// RR_Header is the header all DNS resource records share.
|
|
type RR_Header struct {
|
|
Name string `dns:"cdomain-name"`
|
|
Rrtype uint16
|
|
Class uint16
|
|
Ttl uint32
|
|
Rdlength uint16 // Length of data after header.
|
|
}
|
|
|
|
// Header returns itself. This is here to make RR_Header implements the RR interface.
|
|
func (h *RR_Header) Header() *RR_Header { return h }
|
|
|
|
// Just to implement the RR interface.
|
|
func (h *RR_Header) copy() RR { return nil }
|
|
|
|
func (h *RR_Header) String() string {
|
|
var s string
|
|
|
|
if h.Rrtype == TypeOPT {
|
|
s = ";"
|
|
// and maybe other things
|
|
}
|
|
|
|
s += sprintName(h.Name) + "\t"
|
|
s += strconv.FormatInt(int64(h.Ttl), 10) + "\t"
|
|
s += Class(h.Class).String() + "\t"
|
|
s += Type(h.Rrtype).String() + "\t"
|
|
return s
|
|
}
|
|
|
|
func (h *RR_Header) len(off int, compression map[string]struct{}) int {
|
|
l := domainNameLen(h.Name, off, compression, true)
|
|
l += 10 // rrtype(2) + class(2) + ttl(4) + rdlength(2)
|
|
return l
|
|
}
|
|
|
|
func (h *RR_Header) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
|
|
// RR_Header has no RDATA to pack.
|
|
return off, nil
|
|
}
|
|
|
|
func (h *RR_Header) unpack(msg []byte, off int) (int, error) {
|
|
panic("dns: internal error: unpack should never be called on RR_Header")
|
|
}
|
|
|
|
func (h *RR_Header) parse(c *zlexer, origin string) *ParseError {
|
|
panic("dns: internal error: parse should never be called on RR_Header")
|
|
}
|
|
|
|
// ToRFC3597 converts a known RR to the unknown RR representation from RFC 3597.
|
|
func (rr *RFC3597) ToRFC3597(r RR) error {
|
|
buf := make([]byte, Len(r)*2)
|
|
headerEnd, off, err := packRR(r, buf, 0, compressionMap{}, false)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
buf = buf[:off]
|
|
|
|
*rr = RFC3597{Hdr: *r.Header()}
|
|
rr.Hdr.Rdlength = uint16(off - headerEnd)
|
|
|
|
if noRdata(rr.Hdr) {
|
|
return nil
|
|
}
|
|
|
|
_, err = rr.unpack(buf, headerEnd)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|