Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • ai3/tools/acmeserver
  • godog/acmeserver
  • svp-bot/acmeserver
3 results
Select Git revision
Show changes
Showing
with 3421 additions and 2560 deletions
......@@ -23,6 +23,8 @@ type call struct {
type singleflight struct {
sync.Mutex // protects m
m map[string]*call // lazily initialized
dontDeleteForTesting bool // this is only to be used by TestConcurrentExchanges
}
// Do executes and returns the results of the given function, making
......@@ -49,9 +51,11 @@ func (g *singleflight) Do(key string, fn func() (*Msg, time.Duration, error)) (v
c.val, c.rtt, c.err = fn()
c.wg.Done()
if !g.dontDeleteForTesting {
g.Lock()
delete(g.m, key)
g.Unlock()
}
return c.val, c.rtt, c.err, c.dups > 0
}
......@@ -14,11 +14,8 @@ func (r *SMIMEA) Sign(usage, selector, matchingType int, cert *x509.Certificate)
r.MatchingType = uint8(matchingType)
r.Certificate, err = CertificateToDANE(r.Selector, r.MatchingType, cert)
if err != nil {
return err
}
return nil
}
// Verify verifies a SMIMEA record against an SSL certificate. If it is OK
// a nil error is returned.
......
package dns
import (
"bytes"
"encoding/binary"
"errors"
"fmt"
"net"
"sort"
"strconv"
"strings"
)
// SVCBKey is the type of the keys used in the SVCB RR.
type SVCBKey uint16
// Keys defined in draft-ietf-dnsop-svcb-https-08 Section 14.3.2.
const (
SVCB_MANDATORY SVCBKey = iota
SVCB_ALPN
SVCB_NO_DEFAULT_ALPN
SVCB_PORT
SVCB_IPV4HINT
SVCB_ECHCONFIG
SVCB_IPV6HINT
SVCB_DOHPATH // draft-ietf-add-svcb-dns-02 Section 9
svcb_RESERVED SVCBKey = 65535
)
var svcbKeyToStringMap = map[SVCBKey]string{
SVCB_MANDATORY: "mandatory",
SVCB_ALPN: "alpn",
SVCB_NO_DEFAULT_ALPN: "no-default-alpn",
SVCB_PORT: "port",
SVCB_IPV4HINT: "ipv4hint",
SVCB_ECHCONFIG: "ech",
SVCB_IPV6HINT: "ipv6hint",
SVCB_DOHPATH: "dohpath",
}
var svcbStringToKeyMap = reverseSVCBKeyMap(svcbKeyToStringMap)
func reverseSVCBKeyMap(m map[SVCBKey]string) map[string]SVCBKey {
n := make(map[string]SVCBKey, len(m))
for u, s := range m {
n[s] = u
}
return n
}
// String takes the numerical code of an SVCB key and returns its name.
// Returns an empty string for reserved keys.
// Accepts unassigned keys as well as experimental/private keys.
func (key SVCBKey) String() string {
if x := svcbKeyToStringMap[key]; x != "" {
return x
}
if key == svcb_RESERVED {
return ""
}
return "key" + strconv.FormatUint(uint64(key), 10)
}
// svcbStringToKey returns the numerical code of an SVCB key.
// Returns svcb_RESERVED for reserved/invalid keys.
// Accepts unassigned keys as well as experimental/private keys.
func svcbStringToKey(s string) SVCBKey {
if strings.HasPrefix(s, "key") {
a, err := strconv.ParseUint(s[3:], 10, 16)
// no leading zeros
// key shouldn't be registered
if err != nil || a == 65535 || s[3] == '0' || svcbKeyToStringMap[SVCBKey(a)] != "" {
return svcb_RESERVED
}
return SVCBKey(a)
}
if key, ok := svcbStringToKeyMap[s]; ok {
return key
}
return svcb_RESERVED
}
func (rr *SVCB) parse(c *zlexer, o string) *ParseError {
l, _ := c.Next()
i, e := strconv.ParseUint(l.token, 10, 16)
if e != nil || l.err {
return &ParseError{l.token, "bad SVCB priority", l}
}
rr.Priority = uint16(i)
c.Next() // zBlank
l, _ = c.Next() // zString
rr.Target = l.token
name, nameOk := toAbsoluteName(l.token, o)
if l.err || !nameOk {
return &ParseError{l.token, "bad SVCB Target", l}
}
rr.Target = name
// Values (if any)
l, _ = c.Next()
var xs []SVCBKeyValue
// Helps require whitespace between pairs.
// Prevents key1000="a"key1001=...
canHaveNextKey := true
for l.value != zNewline && l.value != zEOF {
switch l.value {
case zString:
if !canHaveNextKey {
// The key we can now read was probably meant to be
// a part of the last value.
return &ParseError{l.token, "bad SVCB value quotation", l}
}
// In key=value pairs, value does not have to be quoted unless value
// contains whitespace. And keys don't need to have values.
// Similarly, keys with an equality signs after them don't need values.
// l.token includes at least up to the first equality sign.
idx := strings.IndexByte(l.token, '=')
var key, value string
if idx < 0 {
// Key with no value and no equality sign
key = l.token
} else if idx == 0 {
return &ParseError{l.token, "bad SVCB key", l}
} else {
key, value = l.token[:idx], l.token[idx+1:]
if value == "" {
// We have a key and an equality sign. Maybe we have nothing
// after "=" or we have a double quote.
l, _ = c.Next()
if l.value == zQuote {
// Only needed when value ends with double quotes.
// Any value starting with zQuote ends with it.
canHaveNextKey = false
l, _ = c.Next()
switch l.value {
case zString:
// We have a value in double quotes.
value = l.token
l, _ = c.Next()
if l.value != zQuote {
return &ParseError{l.token, "SVCB unterminated value", l}
}
case zQuote:
// There's nothing in double quotes.
default:
return &ParseError{l.token, "bad SVCB value", l}
}
}
}
}
kv := makeSVCBKeyValue(svcbStringToKey(key))
if kv == nil {
return &ParseError{l.token, "bad SVCB key", l}
}
if err := kv.parse(value); err != nil {
return &ParseError{l.token, err.Error(), l}
}
xs = append(xs, kv)
case zQuote:
return &ParseError{l.token, "SVCB key can't contain double quotes", l}
case zBlank:
canHaveNextKey = true
default:
return &ParseError{l.token, "bad SVCB values", l}
}
l, _ = c.Next()
}
// "In AliasMode, records SHOULD NOT include any SvcParams, and recipients MUST
// ignore any SvcParams that are present."
// However, we don't check rr.Priority == 0 && len(xs) > 0 here
// It is the responsibility of the user of the library to check this.
// This is to encourage the fixing of the source of this error.
rr.Value = xs
return nil
}
// makeSVCBKeyValue returns an SVCBKeyValue struct with the key or nil for reserved keys.
func makeSVCBKeyValue(key SVCBKey) SVCBKeyValue {
switch key {
case SVCB_MANDATORY:
return new(SVCBMandatory)
case SVCB_ALPN:
return new(SVCBAlpn)
case SVCB_NO_DEFAULT_ALPN:
return new(SVCBNoDefaultAlpn)
case SVCB_PORT:
return new(SVCBPort)
case SVCB_IPV4HINT:
return new(SVCBIPv4Hint)
case SVCB_ECHCONFIG:
return new(SVCBECHConfig)
case SVCB_IPV6HINT:
return new(SVCBIPv6Hint)
case SVCB_DOHPATH:
return new(SVCBDoHPath)
case svcb_RESERVED:
return nil
default:
e := new(SVCBLocal)
e.KeyCode = key
return e
}
}
// SVCB RR. See RFC xxxx (https://tools.ietf.org/html/draft-ietf-dnsop-svcb-https-08).
//
// NOTE: The HTTPS/SVCB RFCs are in the draft stage.
// The API, including constants and types related to SVCBKeyValues, may
// change in future versions in accordance with the latest drafts.
type SVCB struct {
Hdr RR_Header
Priority uint16 // If zero, Value must be empty or discarded by the user of this library
Target string `dns:"domain-name"`
Value []SVCBKeyValue `dns:"pairs"`
}
// HTTPS RR. Everything valid for SVCB applies to HTTPS as well.
// Except that the HTTPS record is intended for use with the HTTP and HTTPS protocols.
//
// NOTE: The HTTPS/SVCB RFCs are in the draft stage.
// The API, including constants and types related to SVCBKeyValues, may
// change in future versions in accordance with the latest drafts.
type HTTPS struct {
SVCB
}
func (rr *HTTPS) String() string {
return rr.SVCB.String()
}
func (rr *HTTPS) parse(c *zlexer, o string) *ParseError {
return rr.SVCB.parse(c, o)
}
// SVCBKeyValue defines a key=value pair for the SVCB RR type.
// An SVCB RR can have multiple SVCBKeyValues appended to it.
type SVCBKeyValue interface {
Key() SVCBKey // Key returns the numerical key code.
pack() ([]byte, error) // pack returns the encoded value.
unpack([]byte) error // unpack sets the value.
String() string // String returns the string representation of the value.
parse(string) error // parse sets the value to the given string representation of the value.
copy() SVCBKeyValue // copy returns a deep-copy of the pair.
len() int // len returns the length of value in the wire format.
}
// SVCBMandatory pair adds to required keys that must be interpreted for the RR
// to be functional. If ignored, the whole RRSet must be ignored.
// "port" and "no-default-alpn" are mandatory by default if present,
// so they shouldn't be included here.
//
// It is incumbent upon the user of this library to reject the RRSet if
// or avoid constructing such an RRSet that:
// - "mandatory" is included as one of the keys of mandatory
// - no key is listed multiple times in mandatory
// - all keys listed in mandatory are present
// - escape sequences are not used in mandatory
// - mandatory, when present, lists at least one key
//
// Basic use pattern for creating a mandatory option:
//
// s := &dns.SVCB{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}}
// e := new(dns.SVCBMandatory)
// e.Code = []uint16{dns.SVCB_ALPN}
// s.Value = append(s.Value, e)
// t := new(dns.SVCBAlpn)
// t.Alpn = []string{"xmpp-client"}
// s.Value = append(s.Value, t)
type SVCBMandatory struct {
Code []SVCBKey
}
func (*SVCBMandatory) Key() SVCBKey { return SVCB_MANDATORY }
func (s *SVCBMandatory) String() string {
str := make([]string, len(s.Code))
for i, e := range s.Code {
str[i] = e.String()
}
return strings.Join(str, ",")
}
func (s *SVCBMandatory) pack() ([]byte, error) {
codes := append([]SVCBKey(nil), s.Code...)
sort.Slice(codes, func(i, j int) bool {
return codes[i] < codes[j]
})
b := make([]byte, 2*len(codes))
for i, e := range codes {
binary.BigEndian.PutUint16(b[2*i:], uint16(e))
}
return b, nil
}
func (s *SVCBMandatory) unpack(b []byte) error {
if len(b)%2 != 0 {
return errors.New("dns: svcbmandatory: value length is not a multiple of 2")
}
codes := make([]SVCBKey, 0, len(b)/2)
for i := 0; i < len(b); i += 2 {
// We assume strictly increasing order.
codes = append(codes, SVCBKey(binary.BigEndian.Uint16(b[i:])))
}
s.Code = codes
return nil
}
func (s *SVCBMandatory) parse(b string) error {
str := strings.Split(b, ",")
codes := make([]SVCBKey, 0, len(str))
for _, e := range str {
codes = append(codes, svcbStringToKey(e))
}
s.Code = codes
return nil
}
func (s *SVCBMandatory) len() int {
return 2 * len(s.Code)
}
func (s *SVCBMandatory) copy() SVCBKeyValue {
return &SVCBMandatory{
append([]SVCBKey(nil), s.Code...),
}
}
// SVCBAlpn pair is used to list supported connection protocols.
// The user of this library must ensure that at least one protocol is listed when alpn is present.
// Protocol IDs can be found at:
// https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids
// Basic use pattern for creating an alpn option:
//
// h := new(dns.HTTPS)
// h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}
// e := new(dns.SVCBAlpn)
// e.Alpn = []string{"h2", "http/1.1"}
// h.Value = append(h.Value, e)
type SVCBAlpn struct {
Alpn []string
}
func (*SVCBAlpn) Key() SVCBKey { return SVCB_ALPN }
func (s *SVCBAlpn) String() string {
// An ALPN value is a comma-separated list of values, each of which can be
// an arbitrary binary value. In order to allow parsing, the comma and
// backslash characters are themselves excaped.
//
// However, this escaping is done in addition to the normal escaping which
// happens in zone files, meaning that these values must be
// double-escaped. This looks terrible, so if you see a never-ending
// sequence of backslash in a zone file this may be why.
//
// https://datatracker.ietf.org/doc/html/draft-ietf-dnsop-svcb-https-08#appendix-A.1
var str strings.Builder
for i, alpn := range s.Alpn {
// 4*len(alpn) is the worst case where we escape every character in the alpn as \123, plus 1 byte for the ',' separating the alpn from others
str.Grow(4*len(alpn) + 1)
if i > 0 {
str.WriteByte(',')
}
for j := 0; j < len(alpn); j++ {
e := alpn[j]
if ' ' > e || e > '~' {
str.WriteString(escapeByte(e))
continue
}
switch e {
// We escape a few characters which may confuse humans or parsers.
case '"', ';', ' ':
str.WriteByte('\\')
str.WriteByte(e)
// The comma and backslash characters themselves must be
// doubly-escaped. We use `\\` for the first backslash and
// the escaped numeric value for the other value. We especially
// don't want a comma in the output.
case ',':
str.WriteString(`\\\044`)
case '\\':
str.WriteString(`\\\092`)
default:
str.WriteByte(e)
}
}
}
return str.String()
}
func (s *SVCBAlpn) pack() ([]byte, error) {
// Liberally estimate the size of an alpn as 10 octets
b := make([]byte, 0, 10*len(s.Alpn))
for _, e := range s.Alpn {
if e == "" {
return nil, errors.New("dns: svcbalpn: empty alpn-id")
}
if len(e) > 255 {
return nil, errors.New("dns: svcbalpn: alpn-id too long")
}
b = append(b, byte(len(e)))
b = append(b, e...)
}
return b, nil
}
func (s *SVCBAlpn) unpack(b []byte) error {
// Estimate the size of the smallest alpn as 4 bytes
alpn := make([]string, 0, len(b)/4)
for i := 0; i < len(b); {
length := int(b[i])
i++
if i+length > len(b) {
return errors.New("dns: svcbalpn: alpn array overflowing")
}
alpn = append(alpn, string(b[i:i+length]))
i += length
}
s.Alpn = alpn
return nil
}
func (s *SVCBAlpn) parse(b string) error {
if len(b) == 0 {
s.Alpn = []string{}
return nil
}
alpn := []string{}
a := []byte{}
for p := 0; p < len(b); {
c, q := nextByte(b, p)
if q == 0 {
return errors.New("dns: svcbalpn: unterminated escape")
}
p += q
// If we find a comma, we have finished reading an alpn.
if c == ',' {
if len(a) == 0 {
return errors.New("dns: svcbalpn: empty protocol identifier")
}
alpn = append(alpn, string(a))
a = []byte{}
continue
}
// If it's a backslash, we need to handle a comma-separated list.
if c == '\\' {
dc, dq := nextByte(b, p)
if dq == 0 {
return errors.New("dns: svcbalpn: unterminated escape decoding comma-separated list")
}
if dc != '\\' && dc != ',' {
return errors.New("dns: svcbalpn: bad escaped character decoding comma-separated list")
}
p += dq
c = dc
}
a = append(a, c)
}
// Add the final alpn.
if len(a) == 0 {
return errors.New("dns: svcbalpn: last protocol identifier empty")
}
s.Alpn = append(alpn, string(a))
return nil
}
func (s *SVCBAlpn) len() int {
var l int
for _, e := range s.Alpn {
l += 1 + len(e)
}
return l
}
func (s *SVCBAlpn) copy() SVCBKeyValue {
return &SVCBAlpn{
append([]string(nil), s.Alpn...),
}
}
// SVCBNoDefaultAlpn pair signifies no support for default connection protocols.
// Should be used in conjunction with alpn.
// Basic use pattern for creating a no-default-alpn option:
//
// s := &dns.SVCB{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}}
// t := new(dns.SVCBAlpn)
// t.Alpn = []string{"xmpp-client"}
// s.Value = append(s.Value, t)
// e := new(dns.SVCBNoDefaultAlpn)
// s.Value = append(s.Value, e)
type SVCBNoDefaultAlpn struct{}
func (*SVCBNoDefaultAlpn) Key() SVCBKey { return SVCB_NO_DEFAULT_ALPN }
func (*SVCBNoDefaultAlpn) copy() SVCBKeyValue { return &SVCBNoDefaultAlpn{} }
func (*SVCBNoDefaultAlpn) pack() ([]byte, error) { return []byte{}, nil }
func (*SVCBNoDefaultAlpn) String() string { return "" }
func (*SVCBNoDefaultAlpn) len() int { return 0 }
func (*SVCBNoDefaultAlpn) unpack(b []byte) error {
if len(b) != 0 {
return errors.New("dns: svcbnodefaultalpn: no-default-alpn must have no value")
}
return nil
}
func (*SVCBNoDefaultAlpn) parse(b string) error {
if b != "" {
return errors.New("dns: svcbnodefaultalpn: no-default-alpn must have no value")
}
return nil
}
// SVCBPort pair defines the port for connection.
// Basic use pattern for creating a port option:
//
// s := &dns.SVCB{Hdr: dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}}
// e := new(dns.SVCBPort)
// e.Port = 80
// s.Value = append(s.Value, e)
type SVCBPort struct {
Port uint16
}
func (*SVCBPort) Key() SVCBKey { return SVCB_PORT }
func (*SVCBPort) len() int { return 2 }
func (s *SVCBPort) String() string { return strconv.FormatUint(uint64(s.Port), 10) }
func (s *SVCBPort) copy() SVCBKeyValue { return &SVCBPort{s.Port} }
func (s *SVCBPort) unpack(b []byte) error {
if len(b) != 2 {
return errors.New("dns: svcbport: port length is not exactly 2 octets")
}
s.Port = binary.BigEndian.Uint16(b)
return nil
}
func (s *SVCBPort) pack() ([]byte, error) {
b := make([]byte, 2)
binary.BigEndian.PutUint16(b, s.Port)
return b, nil
}
func (s *SVCBPort) parse(b string) error {
port, err := strconv.ParseUint(b, 10, 16)
if err != nil {
return errors.New("dns: svcbport: port out of range")
}
s.Port = uint16(port)
return nil
}
// SVCBIPv4Hint pair suggests an IPv4 address which may be used to open connections
// if A and AAAA record responses for SVCB's Target domain haven't been received.
// In that case, optionally, A and AAAA requests can be made, after which the connection
// to the hinted IP address may be terminated and a new connection may be opened.
// Basic use pattern for creating an ipv4hint option:
//
// h := new(dns.HTTPS)
// h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}
// e := new(dns.SVCBIPv4Hint)
// e.Hint = []net.IP{net.IPv4(1,1,1,1).To4()}
//
// Or
//
// e.Hint = []net.IP{net.ParseIP("1.1.1.1").To4()}
// h.Value = append(h.Value, e)
type SVCBIPv4Hint struct {
Hint []net.IP
}
func (*SVCBIPv4Hint) Key() SVCBKey { return SVCB_IPV4HINT }
func (s *SVCBIPv4Hint) len() int { return 4 * len(s.Hint) }
func (s *SVCBIPv4Hint) pack() ([]byte, error) {
b := make([]byte, 0, 4*len(s.Hint))
for _, e := range s.Hint {
x := e.To4()
if x == nil {
return nil, errors.New("dns: svcbipv4hint: expected ipv4, hint is ipv6")
}
b = append(b, x...)
}
return b, nil
}
func (s *SVCBIPv4Hint) unpack(b []byte) error {
if len(b) == 0 || len(b)%4 != 0 {
return errors.New("dns: svcbipv4hint: ipv4 address byte array length is not a multiple of 4")
}
x := make([]net.IP, 0, len(b)/4)
for i := 0; i < len(b); i += 4 {
x = append(x, net.IP(b[i:i+4]))
}
s.Hint = x
return nil
}
func (s *SVCBIPv4Hint) String() string {
str := make([]string, len(s.Hint))
for i, e := range s.Hint {
x := e.To4()
if x == nil {
return "<nil>"
}
str[i] = x.String()
}
return strings.Join(str, ",")
}
func (s *SVCBIPv4Hint) parse(b string) error {
if strings.Contains(b, ":") {
return errors.New("dns: svcbipv4hint: expected ipv4, got ipv6")
}
str := strings.Split(b, ",")
dst := make([]net.IP, len(str))
for i, e := range str {
ip := net.ParseIP(e).To4()
if ip == nil {
return errors.New("dns: svcbipv4hint: bad ip")
}
dst[i] = ip
}
s.Hint = dst
return nil
}
func (s *SVCBIPv4Hint) copy() SVCBKeyValue {
hint := make([]net.IP, len(s.Hint))
for i, ip := range s.Hint {
hint[i] = copyIP(ip)
}
return &SVCBIPv4Hint{
Hint: hint,
}
}
// SVCBECHConfig pair contains the ECHConfig structure defined in draft-ietf-tls-esni [RFC xxxx].
// Basic use pattern for creating an ech option:
//
// h := new(dns.HTTPS)
// h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}
// e := new(dns.SVCBECHConfig)
// e.ECH = []byte{0xfe, 0x08, ...}
// h.Value = append(h.Value, e)
type SVCBECHConfig struct {
ECH []byte // Specifically ECHConfigList including the redundant length prefix
}
func (*SVCBECHConfig) Key() SVCBKey { return SVCB_ECHCONFIG }
func (s *SVCBECHConfig) String() string { return toBase64(s.ECH) }
func (s *SVCBECHConfig) len() int { return len(s.ECH) }
func (s *SVCBECHConfig) pack() ([]byte, error) {
return append([]byte(nil), s.ECH...), nil
}
func (s *SVCBECHConfig) copy() SVCBKeyValue {
return &SVCBECHConfig{
append([]byte(nil), s.ECH...),
}
}
func (s *SVCBECHConfig) unpack(b []byte) error {
s.ECH = append([]byte(nil), b...)
return nil
}
func (s *SVCBECHConfig) parse(b string) error {
x, err := fromBase64([]byte(b))
if err != nil {
return errors.New("dns: svcbech: bad base64 ech")
}
s.ECH = x
return nil
}
// SVCBIPv6Hint pair suggests an IPv6 address which may be used to open connections
// if A and AAAA record responses for SVCB's Target domain haven't been received.
// In that case, optionally, A and AAAA requests can be made, after which the
// connection to the hinted IP address may be terminated and a new connection may be opened.
// Basic use pattern for creating an ipv6hint option:
//
// h := new(dns.HTTPS)
// h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}
// e := new(dns.SVCBIPv6Hint)
// e.Hint = []net.IP{net.ParseIP("2001:db8::1")}
// h.Value = append(h.Value, e)
type SVCBIPv6Hint struct {
Hint []net.IP
}
func (*SVCBIPv6Hint) Key() SVCBKey { return SVCB_IPV6HINT }
func (s *SVCBIPv6Hint) len() int { return 16 * len(s.Hint) }
func (s *SVCBIPv6Hint) pack() ([]byte, error) {
b := make([]byte, 0, 16*len(s.Hint))
for _, e := range s.Hint {
if len(e) != net.IPv6len || e.To4() != nil {
return nil, errors.New("dns: svcbipv6hint: expected ipv6, hint is ipv4")
}
b = append(b, e...)
}
return b, nil
}
func (s *SVCBIPv6Hint) unpack(b []byte) error {
if len(b) == 0 || len(b)%16 != 0 {
return errors.New("dns: svcbipv6hint: ipv6 address byte array length not a multiple of 16")
}
x := make([]net.IP, 0, len(b)/16)
for i := 0; i < len(b); i += 16 {
ip := net.IP(b[i : i+16])
if ip.To4() != nil {
return errors.New("dns: svcbipv6hint: expected ipv6, got ipv4")
}
x = append(x, ip)
}
s.Hint = x
return nil
}
func (s *SVCBIPv6Hint) String() string {
str := make([]string, len(s.Hint))
for i, e := range s.Hint {
if x := e.To4(); x != nil {
return "<nil>"
}
str[i] = e.String()
}
return strings.Join(str, ",")
}
func (s *SVCBIPv6Hint) parse(b string) error {
str := strings.Split(b, ",")
dst := make([]net.IP, len(str))
for i, e := range str {
ip := net.ParseIP(e)
if ip == nil {
return errors.New("dns: svcbipv6hint: bad ip")
}
if ip.To4() != nil {
return errors.New("dns: svcbipv6hint: expected ipv6, got ipv4-mapped-ipv6")
}
dst[i] = ip
}
s.Hint = dst
return nil
}
func (s *SVCBIPv6Hint) copy() SVCBKeyValue {
hint := make([]net.IP, len(s.Hint))
for i, ip := range s.Hint {
hint[i] = copyIP(ip)
}
return &SVCBIPv6Hint{
Hint: hint,
}
}
// SVCBDoHPath pair is used to indicate the URI template that the
// clients may use to construct a DNS over HTTPS URI.
//
// See RFC xxxx (https://datatracker.ietf.org/doc/html/draft-ietf-add-svcb-dns-02)
// and RFC yyyy (https://datatracker.ietf.org/doc/html/draft-ietf-add-ddr-06).
//
// A basic example of using the dohpath option together with the alpn
// option to indicate support for DNS over HTTPS on a certain path:
//
// s := new(dns.SVCB)
// s.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeSVCB, Class: dns.ClassINET}
// e := new(dns.SVCBAlpn)
// e.Alpn = []string{"h2", "h3"}
// p := new(dns.SVCBDoHPath)
// p.Template = "/dns-query{?dns}"
// s.Value = append(s.Value, e, p)
//
// The parsing currently doesn't validate that Template is a valid
// RFC 6570 URI template.
type SVCBDoHPath struct {
Template string
}
func (*SVCBDoHPath) Key() SVCBKey { return SVCB_DOHPATH }
func (s *SVCBDoHPath) String() string { return svcbParamToStr([]byte(s.Template)) }
func (s *SVCBDoHPath) len() int { return len(s.Template) }
func (s *SVCBDoHPath) pack() ([]byte, error) { return []byte(s.Template), nil }
func (s *SVCBDoHPath) unpack(b []byte) error {
s.Template = string(b)
return nil
}
func (s *SVCBDoHPath) parse(b string) error {
template, err := svcbParseParam(b)
if err != nil {
return fmt.Errorf("dns: svcbdohpath: %w", err)
}
s.Template = string(template)
return nil
}
func (s *SVCBDoHPath) copy() SVCBKeyValue {
return &SVCBDoHPath{
Template: s.Template,
}
}
// SVCBLocal pair is intended for experimental/private use. The key is recommended
// to be in the range [SVCB_PRIVATE_LOWER, SVCB_PRIVATE_UPPER].
// Basic use pattern for creating a keyNNNNN option:
//
// h := new(dns.HTTPS)
// h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}
// e := new(dns.SVCBLocal)
// e.KeyCode = 65400
// e.Data = []byte("abc")
// h.Value = append(h.Value, e)
type SVCBLocal struct {
KeyCode SVCBKey // Never 65535 or any assigned keys.
Data []byte // All byte sequences are allowed.
}
func (s *SVCBLocal) Key() SVCBKey { return s.KeyCode }
func (s *SVCBLocal) String() string { return svcbParamToStr(s.Data) }
func (s *SVCBLocal) pack() ([]byte, error) { return append([]byte(nil), s.Data...), nil }
func (s *SVCBLocal) len() int { return len(s.Data) }
func (s *SVCBLocal) unpack(b []byte) error {
s.Data = append([]byte(nil), b...)
return nil
}
func (s *SVCBLocal) parse(b string) error {
data, err := svcbParseParam(b)
if err != nil {
return fmt.Errorf("dns: svcblocal: svcb private/experimental key %w", err)
}
s.Data = data
return nil
}
func (s *SVCBLocal) copy() SVCBKeyValue {
return &SVCBLocal{s.KeyCode,
append([]byte(nil), s.Data...),
}
}
func (rr *SVCB) String() string {
s := rr.Hdr.String() +
strconv.Itoa(int(rr.Priority)) + " " +
sprintName(rr.Target)
for _, e := range rr.Value {
s += " " + e.Key().String() + "=\"" + e.String() + "\""
}
return s
}
// areSVCBPairArraysEqual checks if SVCBKeyValue arrays are equal after sorting their
// copies. arrA and arrB have equal lengths, otherwise zduplicate.go wouldn't call this function.
func areSVCBPairArraysEqual(a []SVCBKeyValue, b []SVCBKeyValue) bool {
a = append([]SVCBKeyValue(nil), a...)
b = append([]SVCBKeyValue(nil), b...)
sort.Slice(a, func(i, j int) bool { return a[i].Key() < a[j].Key() })
sort.Slice(b, func(i, j int) bool { return b[i].Key() < b[j].Key() })
for i, e := range a {
if e.Key() != b[i].Key() {
return false
}
b1, err1 := e.pack()
b2, err2 := b[i].pack()
if err1 != nil || err2 != nil || !bytes.Equal(b1, b2) {
return false
}
}
return true
}
// svcbParamStr converts the value of an SVCB parameter into a DNS presentation-format string.
func svcbParamToStr(s []byte) string {
var str strings.Builder
str.Grow(4 * len(s))
for _, e := range s {
if ' ' <= e && e <= '~' {
switch e {
case '"', ';', ' ', '\\':
str.WriteByte('\\')
str.WriteByte(e)
default:
str.WriteByte(e)
}
} else {
str.WriteString(escapeByte(e))
}
}
return str.String()
}
// svcbParseParam parses a DNS presentation-format string into an SVCB parameter value.
func svcbParseParam(b string) ([]byte, error) {
data := make([]byte, 0, len(b))
for i := 0; i < len(b); {
if b[i] != '\\' {
data = append(data, b[i])
i++
continue
}
if i+1 == len(b) {
return nil, errors.New("escape unterminated")
}
if isDigit(b[i+1]) {
if i+3 < len(b) && isDigit(b[i+2]) && isDigit(b[i+3]) {
a, err := strconv.ParseUint(b[i+1:i+4], 10, 8)
if err == nil {
i += 4
data = append(data, byte(a))
continue
}
}
return nil, errors.New("bad escaped octet")
} else {
data = append(data, b[i+1])
i += 2
}
}
return data, nil
}
......@@ -14,11 +14,8 @@ func (r *TLSA) Sign(usage, selector, matchingType int, cert *x509.Certificate) (
r.MatchingType = uint8(matchingType)
r.Certificate, err = CertificateToDANE(r.Selector, r.MatchingType, cert)
if err != nil {
return err
}
return nil
}
// Verify verifies a TLSA record against an SSL certificate. If it is OK
// a nil error is returned.
......
// +build tools
// We include our tool dependencies for `go generate` here to ensure they're
// properly tracked by the go tool. See the Go Wiki for the rationale behind this:
// https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module.
package dns
import _ "golang.org/x/tools/go/packages"
......@@ -2,7 +2,6 @@ package dns
import (
"crypto/hmac"
"crypto/md5"
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
......@@ -16,12 +15,83 @@ import (
// HMAC hashing codes. These are transmitted as domain names.
const (
HmacMD5 = "hmac-md5.sig-alg.reg.int."
HmacSHA1 = "hmac-sha1."
HmacSHA224 = "hmac-sha224."
HmacSHA256 = "hmac-sha256."
HmacSHA384 = "hmac-sha384."
HmacSHA512 = "hmac-sha512."
HmacMD5 = "hmac-md5.sig-alg.reg.int." // Deprecated: HmacMD5 is no longer supported.
)
// TsigProvider provides the API to plug-in a custom TSIG implementation.
type TsigProvider interface {
// Generate is passed the DNS message to be signed and the partial TSIG RR. It returns the signature and nil, otherwise an error.
Generate(msg []byte, t *TSIG) ([]byte, error)
// Verify is passed the DNS message to be verified and the TSIG RR. If the signature is valid it will return nil, otherwise an error.
Verify(msg []byte, t *TSIG) error
}
type tsigHMACProvider string
func (key tsigHMACProvider) Generate(msg []byte, t *TSIG) ([]byte, error) {
// If we barf here, the caller is to blame
rawsecret, err := fromBase64([]byte(key))
if err != nil {
return nil, err
}
var h hash.Hash
switch CanonicalName(t.Algorithm) {
case HmacSHA1:
h = hmac.New(sha1.New, rawsecret)
case HmacSHA224:
h = hmac.New(sha256.New224, rawsecret)
case HmacSHA256:
h = hmac.New(sha256.New, rawsecret)
case HmacSHA384:
h = hmac.New(sha512.New384, rawsecret)
case HmacSHA512:
h = hmac.New(sha512.New, rawsecret)
default:
return nil, ErrKeyAlg
}
h.Write(msg)
return h.Sum(nil), nil
}
func (key tsigHMACProvider) Verify(msg []byte, t *TSIG) error {
b, err := key.Generate(msg, t)
if err != nil {
return err
}
mac, err := hex.DecodeString(t.MAC)
if err != nil {
return err
}
if !hmac.Equal(b, mac) {
return ErrSig
}
return nil
}
type tsigSecretProvider map[string]string
func (ts tsigSecretProvider) Generate(msg []byte, t *TSIG) ([]byte, error) {
key, ok := ts[t.Hdr.Name]
if !ok {
return nil, ErrSecret
}
return tsigHMACProvider(key).Generate(msg, t)
}
func (ts tsigSecretProvider) Verify(msg []byte, t *TSIG) error {
key, ok := ts[t.Hdr.Name]
if !ok {
return ErrSecret
}
return tsigHMACProvider(key).Verify(msg, t)
}
// TSIG is the RR the holds the transaction signature of a message.
// See RFC 2845 and RFC 4635.
type TSIG struct {
......@@ -40,7 +110,7 @@ type TSIG struct {
// TSIG has no official presentation format, but this will suffice.
func (rr *TSIG) String() string {
s := "\n;; TSIG PSEUDOSECTION:\n"
s := "\n;; TSIG PSEUDOSECTION:\n; " // add another semi-colon to signify TSIG does not have a presentation format
s += rr.Hdr.String() +
" " + rr.Algorithm +
" " + tsigTimeToString(rr.TimeSigned) +
......@@ -54,6 +124,10 @@ func (rr *TSIG) String() string {
return s
}
func (*TSIG) parse(c *zlexer, origin string) *ParseError {
return &ParseError{err: "TSIG records do not have a presentation format"}
}
// The following values must be put in wireformat, so that the MAC can be calculated.
// RFC 2845, section 3.4.2. TSIG Variables.
type tsigWireFmt struct {
......@@ -84,22 +158,20 @@ type timerWireFmt struct {
}
// TsigGenerate fills out the TSIG record attached to the message.
// The message should contain
// a "stub" TSIG RR with the algorithm, key name (owner name of the RR),
// time fudge (defaults to 300 seconds) and the current time
// The TSIG MAC is saved in that Tsig RR.
// When TsigGenerate is called for the first time requestMAC is set to the empty string and
// timersOnly is false.
// If something goes wrong an error is returned, otherwise it is nil.
// The message should contain a "stub" TSIG RR with the algorithm, key name
// (owner name of the RR), time fudge (defaults to 300 seconds) and the current
// time The TSIG MAC is saved in that Tsig RR. When TsigGenerate is called for
// the first time requestMAC should be set to the empty string and timersOnly to
// false.
func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, string, error) {
return TsigGenerateWithProvider(m, tsigHMACProvider(secret), requestMAC, timersOnly)
}
// TsigGenerateWithProvider is similar to TsigGenerate, but allows for a custom TsigProvider.
func TsigGenerateWithProvider(m *Msg, provider TsigProvider, requestMAC string, timersOnly bool) ([]byte, string, error) {
if m.IsTsig() == nil {
panic("dns: TSIG not last RR in additional")
}
// If we barf here, the caller is to blame
rawsecret, err := fromBase64([]byte(secret))
if err != nil {
return nil, "", err
}
rr := m.Extra[len(m.Extra)-1].(*TSIG)
m.Extra = m.Extra[0 : len(m.Extra)-1] // kill the TSIG from the msg
......@@ -107,69 +179,75 @@ func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, s
if err != nil {
return nil, "", err
}
buf := tsigBuffer(mbuf, rr, requestMAC, timersOnly)
t := new(TSIG)
var h hash.Hash
switch strings.ToLower(rr.Algorithm) {
case HmacMD5:
h = hmac.New(md5.New, []byte(rawsecret))
case HmacSHA1:
h = hmac.New(sha1.New, []byte(rawsecret))
case HmacSHA256:
h = hmac.New(sha256.New, []byte(rawsecret))
case HmacSHA512:
h = hmac.New(sha512.New, []byte(rawsecret))
default:
return nil, "", ErrKeyAlg
buf, err := tsigBuffer(mbuf, rr, requestMAC, timersOnly)
if err != nil {
return nil, "", err
}
h.Write(buf)
t.MAC = hex.EncodeToString(h.Sum(nil))
t.MACSize = uint16(len(t.MAC) / 2) // Size is half!
t.Hdr = RR_Header{Name: rr.Hdr.Name, Rrtype: TypeTSIG, Class: ClassANY, Ttl: 0}
t.Fudge = rr.Fudge
t := new(TSIG)
// Copy all TSIG fields except MAC, its size, and time signed which are filled when signing.
*t = *rr
t.TimeSigned = 0
t.MAC = ""
t.MACSize = 0
// Sign unless there is a key or MAC validation error (RFC 8945 5.3.2)
if rr.Error != RcodeBadKey && rr.Error != RcodeBadSig {
mac, err := provider.Generate(buf, rr)
if err != nil {
return nil, "", err
}
t.TimeSigned = rr.TimeSigned
t.Algorithm = rr.Algorithm
t.OrigId = m.Id
t.MAC = hex.EncodeToString(mac)
t.MACSize = uint16(len(t.MAC) / 2) // Size is half!
}
tbuf := make([]byte, t.len())
if off, err := PackRR(t, tbuf, 0, nil, false); err == nil {
tbuf = tbuf[:off] // reset to actual size used
} else {
tbuf := make([]byte, Len(t))
off, err := PackRR(t, tbuf, 0, nil, false)
if err != nil {
return nil, "", err
}
mbuf = append(mbuf, tbuf...)
mbuf = append(mbuf, tbuf[:off]...)
// Update the ArCount directly in the buffer.
binary.BigEndian.PutUint16(mbuf[10:], uint16(len(m.Extra)+1))
return mbuf, t.MAC, nil
}
// TsigVerify verifies the TSIG on a message.
// If the signature does not validate err contains the
// error, otherwise it is nil.
// TsigVerify verifies the TSIG on a message. If the signature does not
// validate the returned error contains the cause. If the signature is OK, the
// error is nil.
func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) error {
rawsecret, err := fromBase64([]byte(secret))
if err != nil {
return err
return tsigVerify(msg, tsigHMACProvider(secret), requestMAC, timersOnly, uint64(time.Now().Unix()))
}
// TsigVerifyWithProvider is similar to TsigVerify, but allows for a custom TsigProvider.
func TsigVerifyWithProvider(msg []byte, provider TsigProvider, requestMAC string, timersOnly bool) error {
return tsigVerify(msg, provider, requestMAC, timersOnly, uint64(time.Now().Unix()))
}
// actual implementation of TsigVerify, taking the current time ('now') as a parameter for the convenience of tests.
func tsigVerify(msg []byte, provider TsigProvider, requestMAC string, timersOnly bool, now uint64) error {
// Strip the TSIG from the incoming msg
stripped, tsig, err := stripTsig(msg)
if err != nil {
return err
}
msgMAC, err := hex.DecodeString(tsig.MAC)
buf, err := tsigBuffer(stripped, tsig, requestMAC, timersOnly)
if err != nil {
return err
}
buf := tsigBuffer(stripped, tsig, requestMAC, timersOnly)
if err := provider.Verify(buf, tsig); err != nil {
return err
}
// Fudge factor works both ways. A message can arrive before it was signed because
// of clock skew.
now := uint64(time.Now().Unix())
// We check this after verifying the signature, following draft-ietf-dnsop-rfc2845bis
// instead of RFC2845, in order to prevent a security vulnerability as reported in CVE-2017-3142/3143.
ti := now - tsig.TimeSigned
if now < tsig.TimeSigned {
ti = tsig.TimeSigned - now
......@@ -178,28 +256,11 @@ func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) error {
return ErrTime
}
var h hash.Hash
switch strings.ToLower(tsig.Algorithm) {
case HmacMD5:
h = hmac.New(md5.New, rawsecret)
case HmacSHA1:
h = hmac.New(sha1.New, rawsecret)
case HmacSHA256:
h = hmac.New(sha256.New, rawsecret)
case HmacSHA512:
h = hmac.New(sha512.New, rawsecret)
default:
return ErrKeyAlg
}
h.Write(buf)
if !hmac.Equal(h.Sum(nil), msgMAC) {
return ErrSig
}
return nil
}
// Create a wiredata buffer for the MAC calculation.
func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) []byte {
func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) ([]byte, error) {
var buf []byte
if rr.TimeSigned == 0 {
rr.TimeSigned = uint64(time.Now().Unix())
......@@ -216,7 +277,10 @@ func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) []b
m.MACSize = uint16(len(requestMAC) / 2)
m.MAC = requestMAC
buf = make([]byte, len(requestMAC)) // long enough
n, _ := packMacWire(m, buf)
n, err := packMacWire(m, buf)
if err != nil {
return nil, err
}
buf = buf[:n]
}
......@@ -225,20 +289,26 @@ func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) []b
tsig := new(timerWireFmt)
tsig.TimeSigned = rr.TimeSigned
tsig.Fudge = rr.Fudge
n, _ := packTimerWire(tsig, tsigvar)
n, err := packTimerWire(tsig, tsigvar)
if err != nil {
return nil, err
}
tsigvar = tsigvar[:n]
} else {
tsig := new(tsigWireFmt)
tsig.Name = strings.ToLower(rr.Hdr.Name)
tsig.Name = CanonicalName(rr.Hdr.Name)
tsig.Class = ClassANY
tsig.Ttl = rr.Hdr.Ttl
tsig.Algorithm = strings.ToLower(rr.Algorithm)
tsig.Algorithm = CanonicalName(rr.Algorithm)
tsig.TimeSigned = rr.TimeSigned
tsig.Fudge = rr.Fudge
tsig.Error = rr.Error
tsig.OtherLen = rr.OtherLen
tsig.OtherData = rr.OtherData
n, _ := packTsigWire(tsig, tsigvar)
n, err := packTsigWire(tsig, tsigvar)
if err != nil {
return nil, err
}
tsigvar = tsigvar[:n]
}
......@@ -248,7 +318,7 @@ func tsigBuffer(msgbuf []byte, rr *TSIG, requestMAC string, timersOnly bool) []b
} else {
buf = append(msgbuf, tsigvar...)
}
return buf
return buf, nil
}
// Strip the TSIG from the raw message.
......
package dns
import (
"bytes"
"fmt"
"net"
"strconv"
......@@ -61,6 +62,7 @@ const (
TypeCERT uint16 = 37
TypeDNAME uint16 = 39
TypeOPT uint16 = 41 // EDNS
TypeAPL uint16 = 42
TypeDS uint16 = 43
TypeSSHFP uint16 = 44
TypeRRSIG uint16 = 46
......@@ -79,6 +81,9 @@ const (
TypeCDNSKEY uint16 = 60
TypeOPENPGPKEY uint16 = 61
TypeCSYNC uint16 = 62
TypeZONEMD uint16 = 63
TypeSVCB uint16 = 64
TypeHTTPS uint16 = 65
TypeSPF uint16 = 99
TypeUINFO uint16 = 100
TypeUID uint16 = 101
......@@ -146,6 +151,14 @@ const (
OpcodeUpdate = 5
)
// Used in ZONEMD https://tools.ietf.org/html/rfc8976
const (
ZoneMDSchemeSimple = 1
ZoneMDHashAlgSHA384 = 1
ZoneMDHashAlgSHA512 = 2
)
// Header is the wire format for the DNS packet header.
type Header struct {
Id uint16
......@@ -163,11 +176,11 @@ const (
_RD = 1 << 8 // recursion desired
_RA = 1 << 7 // recursion available
_Z = 1 << 6 // Z
_AD = 1 << 5 // authticated data
_AD = 1 << 5 // authenticated data
_CD = 1 << 4 // checking disabled
)
// Various constants used in the LOC RR, See RFC 1887.
// Various constants used in the LOC RR. See RFC 1887.
const (
LOC_EQUATOR = 1 << 31 // RFC 1876, Section 2.
LOC_PRIMEMERIDIAN = 1 << 31 // RFC 1876, Section 2.
......@@ -205,21 +218,23 @@ var CertTypeToString = map[uint16]string{
CertOID: "OID",
}
// StringToCertType is the reverseof CertTypeToString.
var StringToCertType = reverseInt16(CertTypeToString)
//go:generate go run types_generate.go
// Question holds a DNS question. There can be multiple questions in the
// question section of a message. Usually there is just one.
// Question holds a DNS question. Usually there is just one. While the
// original DNS RFCs allow multiple questions in the question section of a
// message, in practice it never works. Because most DNS servers see multiple
// questions as an error, it is recommended to only have one question per
// message.
type Question struct {
Name string `dns:"cdomain-name"` // "cdomain-name" specifies encoding (and may be compressed)
Qtype uint16
Qclass uint16
}
func (q *Question) len() int {
return len(q.Name) + 1 + 2 + 2
func (q *Question) len(off int, compression map[string]struct{}) int {
l := domainNameLen(q.Name, off, compression, true)
l += 2 + 2
return l
}
func (q *Question) String() (s string) {
......@@ -239,6 +254,25 @@ type ANY struct {
func (rr *ANY) String() string { return rr.Hdr.String() }
func (*ANY) parse(c *zlexer, origin string) *ParseError {
return &ParseError{err: "ANY records do not have a presentation format"}
}
// NULL RR. See RFC 1035.
type NULL struct {
Hdr RR_Header
Data string `dns:"any"`
}
func (rr *NULL) String() string {
// There is no presentation format; prefix string with a comment.
return ";" + rr.Hdr.String() + rr.Data
}
func (*NULL) parse(c *zlexer, origin string) *ParseError {
return &ParseError{err: "NULL records do not have a presentation format"}
}
// CNAME RR. See RFC 1034.
type CNAME struct {
Hdr RR_Header
......@@ -351,7 +385,7 @@ func (rr *X25) String() string {
type RT struct {
Hdr RR_Header
Preference uint16
Host string `dns:"cdomain-name"`
Host string `dns:"domain-name"` // RFC 3597 prohibits compressing records not defined in RFC 1035.
}
func (rr *RT) String() string {
......@@ -386,7 +420,7 @@ type RP struct {
}
func (rr *RP) String() string {
return rr.Hdr.String() + rr.Mbox + " " + sprintTxt([]string{rr.Txt})
return rr.Hdr.String() + sprintName(rr.Mbox) + " " + sprintName(rr.Txt)
}
// SOA RR. See RFC 1035.
......@@ -419,128 +453,172 @@ type TXT struct {
func (rr *TXT) String() string { return rr.Hdr.String() + sprintTxt(rr.Txt) }
func sprintName(s string) string {
src := []byte(s)
dst := make([]byte, 0, len(src))
for i := 0; i < len(src); {
if i+1 < len(src) && src[i] == '\\' && src[i+1] == '.' {
dst = append(dst, src[i:i+2]...)
i += 2
} else {
b, n := nextByte(src, i)
var dst strings.Builder
for i := 0; i < len(s); {
if s[i] == '.' {
if dst.Len() != 0 {
dst.WriteByte('.')
}
i++
continue
}
b, n := nextByte(s, i)
if n == 0 {
i++ // dangling back slash
} else if b == '.' {
dst = append(dst, b)
// Drop "dangling" incomplete escapes.
if dst.Len() == 0 {
return s[:i]
}
break
}
if isDomainNameLabelSpecial(b) {
if dst.Len() == 0 {
dst.Grow(len(s) * 2)
dst.WriteString(s[:i])
}
dst.WriteByte('\\')
dst.WriteByte(b)
} else if b < ' ' || b > '~' { // unprintable, use \DDD
if dst.Len() == 0 {
dst.Grow(len(s) * 2)
dst.WriteString(s[:i])
}
dst.WriteString(escapeByte(b))
} else {
dst = appendDomainNameByte(dst, b)
if dst.Len() != 0 {
dst.WriteByte(b)
}
}
i += n
}
if dst.Len() == 0 {
return s
}
return string(dst)
return dst.String()
}
func sprintTxtOctet(s string) string {
src := []byte(s)
dst := make([]byte, 0, len(src))
dst = append(dst, '"')
for i := 0; i < len(src); {
if i+1 < len(src) && src[i] == '\\' && src[i+1] == '.' {
dst = append(dst, src[i:i+2]...)
var dst strings.Builder
dst.Grow(2 + len(s))
dst.WriteByte('"')
for i := 0; i < len(s); {
if i+1 < len(s) && s[i] == '\\' && s[i+1] == '.' {
dst.WriteString(s[i : i+2])
i += 2
} else {
b, n := nextByte(src, i)
continue
}
b, n := nextByte(s, i)
if n == 0 {
i++ // dangling back slash
} else if b == '.' {
dst = append(dst, b)
} else {
if b < ' ' || b > '~' {
dst = appendByte(dst, b)
} else {
dst = append(dst, b)
}
writeTXTStringByte(&dst, b)
}
i += n
}
}
dst = append(dst, '"')
return string(dst)
dst.WriteByte('"')
return dst.String()
}
func sprintTxt(txt []string) string {
var out []byte
var out strings.Builder
for i, s := range txt {
out.Grow(3 + len(s))
if i > 0 {
out = append(out, ` "`...)
out.WriteString(` "`)
} else {
out = append(out, '"')
out.WriteByte('"')
}
bs := []byte(s)
for j := 0; j < len(bs); {
b, n := nextByte(bs, j)
for j := 0; j < len(s); {
b, n := nextByte(s, j)
if n == 0 {
break
}
out = appendTXTStringByte(out, b)
writeTXTStringByte(&out, b)
j += n
}
out = append(out, '"')
out.WriteByte('"')
}
return string(out)
return out.String()
}
func appendDomainNameByte(s []byte, b byte) []byte {
switch b {
case '.', ' ', '\'', '@', ';', '(', ')': // additional chars to escape
return append(s, '\\', b)
func writeTXTStringByte(s *strings.Builder, b byte) {
switch {
case b == '"' || b == '\\':
s.WriteByte('\\')
s.WriteByte(b)
case b < ' ' || b > '~':
s.WriteString(escapeByte(b))
default:
s.WriteByte(b)
}
return appendTXTStringByte(s, b)
}
func appendTXTStringByte(s []byte, b byte) []byte {
switch b {
case '"', '\\':
return append(s, '\\', b)
}
if b < ' ' || b > '~' {
return appendByte(s, b)
}
return append(s, b)
const (
escapedByteSmall = "" +
`\000\001\002\003\004\005\006\007\008\009` +
`\010\011\012\013\014\015\016\017\018\019` +
`\020\021\022\023\024\025\026\027\028\029` +
`\030\031`
escapedByteLarge = `\127\128\129` +
`\130\131\132\133\134\135\136\137\138\139` +
`\140\141\142\143\144\145\146\147\148\149` +
`\150\151\152\153\154\155\156\157\158\159` +
`\160\161\162\163\164\165\166\167\168\169` +
`\170\171\172\173\174\175\176\177\178\179` +
`\180\181\182\183\184\185\186\187\188\189` +
`\190\191\192\193\194\195\196\197\198\199` +
`\200\201\202\203\204\205\206\207\208\209` +
`\210\211\212\213\214\215\216\217\218\219` +
`\220\221\222\223\224\225\226\227\228\229` +
`\230\231\232\233\234\235\236\237\238\239` +
`\240\241\242\243\244\245\246\247\248\249` +
`\250\251\252\253\254\255`
)
// escapeByte returns the \DDD escaping of b which must
// satisfy b < ' ' || b > '~'.
func escapeByte(b byte) string {
if b < ' ' {
return escapedByteSmall[b*4 : b*4+4]
}
func appendByte(s []byte, b byte) []byte {
var buf [3]byte
bufs := strconv.AppendInt(buf[:0], int64(b), 10)
s = append(s, '\\')
for i := 0; i < 3-len(bufs); i++ {
s = append(s, '0')
b -= '~' + 1
// The cast here is needed as b*4 may overflow byte.
return escapedByteLarge[int(b)*4 : int(b)*4+4]
}
for _, r := range bufs {
s = append(s, r)
// isDomainNameLabelSpecial returns true if
// a domain name label byte should be prefixed
// with an escaping backslash.
func isDomainNameLabelSpecial(b byte) bool {
switch b {
case '.', ' ', '\'', '@', ';', '(', ')', '"', '\\':
return true
}
return s
return false
}
func nextByte(b []byte, offset int) (byte, int) {
if offset >= len(b) {
func nextByte(s string, offset int) (byte, int) {
if offset >= len(s) {
return 0, 0
}
if b[offset] != '\\' {
if s[offset] != '\\' {
// not an escape sequence
return b[offset], 1
return s[offset], 1
}
switch len(b) - offset {
switch len(s) - offset {
case 1: // dangling escape
return 0, 0
case 2, 3: // too short to be \ddd
default: // maybe \ddd
if isDigit(b[offset+1]) && isDigit(b[offset+2]) && isDigit(b[offset+3]) {
return dddToByte(b[offset+1:]), 4
if isDigit(s[offset+1]) && isDigit(s[offset+2]) && isDigit(s[offset+3]) {
return dddStringToByte(s[offset+1:]), 4
}
}
// not \ddd, just an RFC 1035 "quoted" character
return b[offset+1], 2
return s[offset+1], 2
}
// SPF RR. See RFC 4408, Section 3.1.1.
......@@ -695,7 +773,7 @@ type LOC struct {
}
// cmToM takes a cm value expressed in RFC 1876 SIZE mantissa/exponent
// format and returns a string in m (two decimals for the cm)
// format and returns a string in m (two decimals for the cm).
func cmToM(m, e uint8) string {
if e < 2 {
if e == 1 {
......@@ -801,22 +879,16 @@ type NSEC struct {
func (rr *NSEC) String() string {
s := rr.Hdr.String() + sprintName(rr.NextDomain)
for i := 0; i < len(rr.TypeBitMap); i++ {
s += " " + Type(rr.TypeBitMap[i]).String()
for _, t := range rr.TypeBitMap {
s += " " + Type(t).String()
}
return s
}
func (rr *NSEC) len() int {
l := rr.Hdr.len() + len(rr.NextDomain) + 1
lastwindow := uint32(2 ^ 32 + 1)
for _, t := range rr.TypeBitMap {
window := t / 256
if uint32(window) != lastwindow {
l += 1 + 32
}
lastwindow = uint32(window)
}
func (rr *NSEC) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += domainNameLen(rr.NextDomain, off+l, compression, false)
l += typeBitMapLen(rr.TypeBitMap)
return l
}
......@@ -966,22 +1038,16 @@ func (rr *NSEC3) String() string {
" " + strconv.Itoa(int(rr.Iterations)) +
" " + saltToString(rr.Salt) +
" " + rr.NextDomain
for i := 0; i < len(rr.TypeBitMap); i++ {
s += " " + Type(rr.TypeBitMap[i]).String()
for _, t := range rr.TypeBitMap {
s += " " + Type(t).String()
}
return s
}
func (rr *NSEC3) len() int {
l := rr.Hdr.len() + 6 + len(rr.Salt)/2 + 1 + len(rr.NextDomain) + 1
lastwindow := uint32(2 ^ 32 + 1)
for _, t := range rr.TypeBitMap {
window := t / 256
if uint32(window) != lastwindow {
l += 1 + 32
}
lastwindow = uint32(window)
}
func (rr *NSEC3) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += 6 + len(rr.Salt)/2 + 1 + len(rr.NextDomain) + 1
l += typeBitMapLen(rr.TypeBitMap)
return l
}
......@@ -1020,10 +1086,16 @@ type TKEY struct {
// TKEY has no official presentation format, but this will suffice.
func (rr *TKEY) String() string {
s := "\n;; TKEY PSEUDOSECTION:\n"
s += rr.Hdr.String() + " " + rr.Algorithm + " " +
strconv.Itoa(int(rr.KeySize)) + " " + rr.Key + " " +
strconv.Itoa(int(rr.OtherLen)) + " " + rr.OtherData
s := ";" + rr.Hdr.String() +
" " + rr.Algorithm +
" " + TimeToString(rr.Inception) +
" " + TimeToString(rr.Expiration) +
" " + strconv.Itoa(int(rr.Mode)) +
" " + strconv.Itoa(int(rr.Error)) +
" " + strconv.Itoa(int(rr.KeySize)) +
" " + rr.Key +
" " + strconv.Itoa(int(rr.OtherLen)) +
" " + rr.OtherData
return s
}
......@@ -1059,6 +1131,7 @@ type URI struct {
Target string `dns:"octet"`
}
// rr.Target to be parsed as a sequence of character encoded octets according to RFC 3986
func (rr *URI) String() string {
return rr.Hdr.String() + strconv.Itoa(int(rr.Priority)) +
" " + strconv.Itoa(int(rr.Weight)) + " " + sprintTxtOctet(rr.Target)
......@@ -1220,6 +1293,7 @@ type CAA struct {
Value string `dns:"octet"`
}
// rr.Value Is the character-string encoding of the value field as specified in RFC 1035, Section 5.1.
func (rr *CAA) String() string {
return rr.Hdr.String() + strconv.Itoa(int(rr.Flag)) + " " + rr.Tag + " " + sprintTxtOctet(rr.Value)
}
......@@ -1283,23 +1357,116 @@ type CSYNC struct {
func (rr *CSYNC) String() string {
s := rr.Hdr.String() + strconv.FormatInt(int64(rr.Serial), 10) + " " + strconv.Itoa(int(rr.Flags))
for i := 0; i < len(rr.TypeBitMap); i++ {
s += " " + Type(rr.TypeBitMap[i]).String()
for _, t := range rr.TypeBitMap {
s += " " + Type(t).String()
}
return s
}
func (rr *CSYNC) len() int {
l := rr.Hdr.len() + 4 + 2
lastwindow := uint32(2 ^ 32 + 1)
for _, t := range rr.TypeBitMap {
window := t / 256
if uint32(window) != lastwindow {
l += 1 + 32
func (rr *CSYNC) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += 4 + 2
l += typeBitMapLen(rr.TypeBitMap)
return l
}
lastwindow = uint32(window)
// ZONEMD RR, from draft-ietf-dnsop-dns-zone-digest
type ZONEMD struct {
Hdr RR_Header
Serial uint32
Scheme uint8
Hash uint8
Digest string `dns:"hex"`
}
return l
func (rr *ZONEMD) String() string {
return rr.Hdr.String() +
strconv.Itoa(int(rr.Serial)) +
" " + strconv.Itoa(int(rr.Scheme)) +
" " + strconv.Itoa(int(rr.Hash)) +
" " + rr.Digest
}
// APL RR. See RFC 3123.
type APL struct {
Hdr RR_Header
Prefixes []APLPrefix `dns:"apl"`
}
// APLPrefix is an address prefix hold by an APL record.
type APLPrefix struct {
Negation bool
Network net.IPNet
}
// String returns presentation form of the APL record.
func (rr *APL) String() string {
var sb strings.Builder
sb.WriteString(rr.Hdr.String())
for i, p := range rr.Prefixes {
if i > 0 {
sb.WriteByte(' ')
}
sb.WriteString(p.str())
}
return sb.String()
}
// str returns presentation form of the APL prefix.
func (a *APLPrefix) str() string {
var sb strings.Builder
if a.Negation {
sb.WriteByte('!')
}
switch len(a.Network.IP) {
case net.IPv4len:
sb.WriteByte('1')
case net.IPv6len:
sb.WriteByte('2')
}
sb.WriteByte(':')
switch len(a.Network.IP) {
case net.IPv4len:
sb.WriteString(a.Network.IP.String())
case net.IPv6len:
// add prefix for IPv4-mapped IPv6
if v4 := a.Network.IP.To4(); v4 != nil {
sb.WriteString("::ffff:")
}
sb.WriteString(a.Network.IP.String())
}
sb.WriteByte('/')
prefix, _ := a.Network.Mask.Size()
sb.WriteString(strconv.Itoa(prefix))
return sb.String()
}
// equals reports whether two APL prefixes are identical.
func (a *APLPrefix) equals(b *APLPrefix) bool {
return a.Negation == b.Negation &&
bytes.Equal(a.Network.IP, b.Network.IP) &&
bytes.Equal(a.Network.Mask, b.Network.Mask)
}
// copy returns a copy of the APL prefix.
func (a *APLPrefix) copy() APLPrefix {
return APLPrefix{
Negation: a.Negation,
Network: copyNet(a.Network),
}
}
// len returns size of the prefix in wire format.
func (a *APLPrefix) len() int {
// 4-byte header and the network address prefix (see Section 4 of RFC 3123)
prefix, _ := a.Network.Mask.Size()
return 4 + (prefix+7)/8
}
// TimeToString translates the RRSIG's incep. and expir. times to the
......@@ -1331,7 +1498,7 @@ func StringToTime(s string) (uint32, error) {
// saltToString converts a NSECX salt to uppercase and returns "-" when it is empty.
func saltToString(s string) string {
if len(s) == 0 {
if s == "" {
return "-"
}
return strings.ToUpper(s)
......@@ -1358,6 +1525,17 @@ func copyIP(ip net.IP) net.IP {
return p
}
// copyNet returns a copy of a subnet.
func copyNet(n net.IPNet) net.IPNet {
m := make(net.IPMask, len(n.Mask))
copy(m, n.Mask)
return net.IPNet{
IP: copyIP(n.IP),
Mask: m,
}
}
// SplitN splits a string into N sized string chunks.
// This might become an exported function once.
func splitN(s string, n int) []string {
......
//+build ignore
// types_generate.go is meant to run with go generate. It will use
// go/{importer,types} to track down all the RR struct types. Then for each type
// it will generate conversion tables (TypeToRR and TypeToString) and banal
// methods (len, Header, copy) based on the struct tags. The generated source is
// written to ztypes.go, and is meant to be checked into git.
package main
import (
"bytes"
"fmt"
"go/format"
"go/importer"
"go/types"
"log"
"os"
"strings"
"text/template"
)
var skipLen = map[string]struct{}{
"NSEC": {},
"NSEC3": {},
"OPT": {},
"CSYNC": {},
}
var packageHdr = `
// Code generated by "go run types_generate.go"; DO NOT EDIT.
package dns
import (
"encoding/base64"
"net"
)
`
var TypeToRR = template.Must(template.New("TypeToRR").Parse(`
// TypeToRR is a map of constructors for each RR type.
var TypeToRR = map[uint16]func() RR{
{{range .}}{{if ne . "RFC3597"}} Type{{.}}: func() RR { return new({{.}}) },
{{end}}{{end}} }
`))
var typeToString = template.Must(template.New("typeToString").Parse(`
// TypeToString is a map of strings for each RR type.
var TypeToString = map[uint16]string{
{{range .}}{{if ne . "NSAPPTR"}} Type{{.}}: "{{.}}",
{{end}}{{end}} TypeNSAPPTR: "NSAP-PTR",
}
`))
var headerFunc = template.Must(template.New("headerFunc").Parse(`
{{range .}} func (rr *{{.}}) Header() *RR_Header { return &rr.Hdr }
{{end}}
`))
// getTypeStruct will take a type and the package scope, and return the
// (innermost) struct if the type is considered a RR type (currently defined as
// those structs beginning with a RR_Header, could be redefined as implementing
// the RR interface). The bool return value indicates if embedded structs were
// resolved.
func getTypeStruct(t types.Type, scope *types.Scope) (*types.Struct, bool) {
st, ok := t.Underlying().(*types.Struct)
if !ok {
return nil, false
}
if st.Field(0).Type() == scope.Lookup("RR_Header").Type() {
return st, false
}
if st.Field(0).Anonymous() {
st, _ := getTypeStruct(st.Field(0).Type(), scope)
return st, true
}
return nil, false
}
func main() {
// Import and type-check the package
pkg, err := importer.Default().Import("github.com/miekg/dns")
fatalIfErr(err)
scope := pkg.Scope()
// Collect constants like TypeX
var numberedTypes []string
for _, name := range scope.Names() {
o := scope.Lookup(name)
if o == nil || !o.Exported() {
continue
}
b, ok := o.Type().(*types.Basic)
if !ok || b.Kind() != types.Uint16 {
continue
}
if !strings.HasPrefix(o.Name(), "Type") {
continue
}
name := strings.TrimPrefix(o.Name(), "Type")
if name == "PrivateRR" {
continue
}
numberedTypes = append(numberedTypes, name)
}
// Collect actual types (*X)
var namedTypes []string
for _, name := range scope.Names() {
o := scope.Lookup(name)
if o == nil || !o.Exported() {
continue
}
if st, _ := getTypeStruct(o.Type(), scope); st == nil {
continue
}
if name == "PrivateRR" {
continue
}
// Check if corresponding TypeX exists
if scope.Lookup("Type"+o.Name()) == nil && o.Name() != "RFC3597" {
log.Fatalf("Constant Type%s does not exist.", o.Name())
}
namedTypes = append(namedTypes, o.Name())
}
b := &bytes.Buffer{}
b.WriteString(packageHdr)
// Generate TypeToRR
fatalIfErr(TypeToRR.Execute(b, namedTypes))
// Generate typeToString
fatalIfErr(typeToString.Execute(b, numberedTypes))
// Generate headerFunc
fatalIfErr(headerFunc.Execute(b, namedTypes))
// Generate len()
fmt.Fprint(b, "// len() functions\n")
for _, name := range namedTypes {
if _, ok := skipLen[name]; ok {
continue
}
o := scope.Lookup(name)
st, isEmbedded := getTypeStruct(o.Type(), scope)
if isEmbedded {
continue
}
fmt.Fprintf(b, "func (rr *%s) len() int {\n", name)
fmt.Fprintf(b, "l := rr.Hdr.len()\n")
for i := 1; i < st.NumFields(); i++ {
o := func(s string) { fmt.Fprintf(b, s, st.Field(i).Name()) }
if _, ok := st.Field(i).Type().(*types.Slice); ok {
switch st.Tag(i) {
case `dns:"-"`:
// ignored
case `dns:"cdomain-name"`, `dns:"domain-name"`, `dns:"txt"`:
o("for _, x := range rr.%s { l += len(x) + 1 }\n")
default:
log.Fatalln(name, st.Field(i).Name(), st.Tag(i))
}
continue
}
switch {
case st.Tag(i) == `dns:"-"`:
// ignored
case st.Tag(i) == `dns:"cdomain-name"`, st.Tag(i) == `dns:"domain-name"`:
o("l += len(rr.%s) + 1\n")
case st.Tag(i) == `dns:"octet"`:
o("l += len(rr.%s)\n")
case strings.HasPrefix(st.Tag(i), `dns:"size-base64`):
fallthrough
case st.Tag(i) == `dns:"base64"`:
o("l += base64.StdEncoding.DecodedLen(len(rr.%s))\n")
case strings.HasPrefix(st.Tag(i), `dns:"size-hex:`): // this has an extra field where the length is stored
o("l += len(rr.%s)/2\n")
case strings.HasPrefix(st.Tag(i), `dns:"size-hex`):
fallthrough
case st.Tag(i) == `dns:"hex"`:
o("l += len(rr.%s)/2 + 1\n")
case st.Tag(i) == `dns:"a"`:
o("l += net.IPv4len // %s\n")
case st.Tag(i) == `dns:"aaaa"`:
o("l += net.IPv6len // %s\n")
case st.Tag(i) == `dns:"txt"`:
o("for _, t := range rr.%s { l += len(t) + 1 }\n")
case st.Tag(i) == `dns:"uint48"`:
o("l += 6 // %s\n")
case st.Tag(i) == "":
switch st.Field(i).Type().(*types.Basic).Kind() {
case types.Uint8:
o("l++ // %s\n")
case types.Uint16:
o("l += 2 // %s\n")
case types.Uint32:
o("l += 4 // %s\n")
case types.Uint64:
o("l += 8 // %s\n")
case types.String:
o("l += len(rr.%s) + 1\n")
default:
log.Fatalln(name, st.Field(i).Name())
}
default:
log.Fatalln(name, st.Field(i).Name(), st.Tag(i))
}
}
fmt.Fprintf(b, "return l }\n")
}
// Generate copy()
fmt.Fprint(b, "// copy() functions\n")
for _, name := range namedTypes {
o := scope.Lookup(name)
st, isEmbedded := getTypeStruct(o.Type(), scope)
if isEmbedded {
continue
}
fmt.Fprintf(b, "func (rr *%s) copy() RR {\n", name)
fields := []string{"rr.Hdr"}
for i := 1; i < st.NumFields(); i++ {
f := st.Field(i).Name()
if sl, ok := st.Field(i).Type().(*types.Slice); ok {
t := sl.Underlying().String()
t = strings.TrimPrefix(t, "[]")
if strings.Contains(t, ".") {
splits := strings.Split(t, ".")
t = splits[len(splits)-1]
}
fmt.Fprintf(b, "%s := make([]%s, len(rr.%s)); copy(%s, rr.%s)\n",
f, t, f, f, f)
fields = append(fields, f)
continue
}
if st.Field(i).Type().String() == "net.IP" {
fields = append(fields, "copyIP(rr."+f+")")
continue
}
fields = append(fields, "rr."+f)
}
fmt.Fprintf(b, "return &%s{%s}\n", name, strings.Join(fields, ","))
fmt.Fprintf(b, "}\n")
}
// gofmt
res, err := format.Source(b.Bytes())
if err != nil {
b.WriteTo(os.Stderr)
log.Fatal(err)
}
// write result
f, err := os.Create("ztypes.go")
fatalIfErr(err)
defer f.Close()
f.Write(res)
}
func fatalIfErr(err error) {
if err != nil {
log.Fatal(err)
}
}
......@@ -20,15 +20,13 @@ func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) {
if err != nil {
return n, nil, err
}
session := &SessionUDP{raddr.(*net.UDPAddr)}
return n, session, err
return n, &SessionUDP{raddr.(*net.UDPAddr)}, err
}
// WriteToSessionUDP acts just like net.UDPConn.WriteTo(), but uses a *SessionUDP instead of a net.Addr.
// TODO(fastest963): Once go1.10 is released, use WriteMsgUDP.
func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, error) {
n, err := conn.WriteTo(b, session.raddr)
return n, err
return conn.WriteTo(b, session.raddr)
}
// TODO(fastest963): Once go1.10 is released and we can use *MsgUDP methods
......
......@@ -32,7 +32,9 @@ func (u *Msg) Used(rr []RR) {
u.Answer = make([]RR, 0, len(rr))
}
for _, r := range rr {
r.Header().Class = u.Question[0].Qclass
hdr := r.Header()
hdr.Class = u.Question[0].Qclass
hdr.Ttl = 0
u.Answer = append(u.Answer, r)
}
}
......@@ -44,7 +46,8 @@ func (u *Msg) RRsetUsed(rr []RR) {
u.Answer = make([]RR, 0, len(rr))
}
for _, r := range rr {
u.Answer = append(u.Answer, &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: r.Header().Rrtype, Class: ClassANY}})
h := r.Header()
u.Answer = append(u.Answer, &ANY{Hdr: RR_Header{Name: h.Name, Ttl: 0, Rrtype: h.Rrtype, Class: ClassANY}})
}
}
......@@ -55,7 +58,8 @@ func (u *Msg) RRsetNotUsed(rr []RR) {
u.Answer = make([]RR, 0, len(rr))
}
for _, r := range rr {
u.Answer = append(u.Answer, &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: r.Header().Rrtype, Class: ClassNONE}})
h := r.Header()
u.Answer = append(u.Answer, &ANY{Hdr: RR_Header{Name: h.Name, Ttl: 0, Rrtype: h.Rrtype, Class: ClassNONE}})
}
}
......@@ -79,7 +83,8 @@ func (u *Msg) RemoveRRset(rr []RR) {
u.Ns = make([]RR, 0, len(rr))
}
for _, r := range rr {
u.Ns = append(u.Ns, &ANY{Hdr: RR_Header{Name: r.Header().Name, Ttl: 0, Rrtype: r.Header().Rrtype, Class: ClassANY}})
h := r.Header()
u.Ns = append(u.Ns, &ANY{Hdr: RR_Header{Name: h.Name, Ttl: 0, Rrtype: h.Rrtype, Class: ClassANY}})
}
}
......@@ -99,8 +104,9 @@ func (u *Msg) Remove(rr []RR) {
u.Ns = make([]RR, 0, len(rr))
}
for _, r := range rr {
r.Header().Class = ClassNONE
r.Header().Ttl = 0
h := r.Header()
h.Class = ClassNONE
h.Ttl = 0
u.Ns = append(u.Ns, r)
}
}
......@@ -3,13 +3,13 @@ package dns
import "fmt"
// Version is current version of this library.
var Version = V{1, 0, 8}
var Version = v{1, 1, 50}
// V holds the version of this library.
type V struct {
// v holds the version of this library.
type v struct {
Major, Minor, Patch int
}
func (v V) String() string {
func (v v) String() string {
return fmt.Sprintf("%d.%d.%d", v.Major, v.Minor, v.Patch)
}
......@@ -17,11 +17,22 @@ type Transfer struct {
DialTimeout time.Duration // net.DialTimeout, defaults to 2 seconds
ReadTimeout time.Duration // net.Conn.SetReadTimeout value for connections, defaults to 2 seconds
WriteTimeout time.Duration // net.Conn.SetWriteTimeout value for connections, defaults to 2 seconds
TsigProvider TsigProvider // An implementation of the TsigProvider interface. If defined it replaces TsigSecret and is used for all TSIG operations.
TsigSecret map[string]string // Secret(s) for Tsig map[<zonename>]<base64 secret>, zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2)
tsigTimersOnly bool
}
// Think we need to away to stop the transfer
func (t *Transfer) tsigProvider() TsigProvider {
if t.TsigProvider != nil {
return t.TsigProvider
}
if t.TsigSecret != nil {
return tsigSecretProvider(t.TsigSecret)
}
return nil
}
// TODO: Think we need to away to stop the transfer
// In performs an incoming transfer with the server in a.
// If you would like to set the source IP, or some other attribute
......@@ -35,30 +46,36 @@ type Transfer struct {
// channel, err := transfer.In(message, master)
//
func (t *Transfer) In(q *Msg, a string) (env chan *Envelope, err error) {
switch q.Question[0].Qtype {
case TypeAXFR, TypeIXFR:
default:
return nil, &Error{"unsupported question type"}
}
timeout := dnsTimeout
if t.DialTimeout != 0 {
timeout = t.DialTimeout
}
if t.Conn == nil {
t.Conn, err = DialTimeout("tcp", a, timeout)
if err != nil {
return nil, err
}
}
if err := t.WriteMsg(q); err != nil {
return nil, err
}
env = make(chan *Envelope)
go func() {
if q.Question[0].Qtype == TypeAXFR {
switch q.Question[0].Qtype {
case TypeAXFR:
go t.inAxfr(q, env)
return
}
if q.Question[0].Qtype == TypeIXFR {
case TypeIXFR:
go t.inIxfr(q, env)
return
}
}()
return env, nil
}
......@@ -111,7 +128,7 @@ func (t *Transfer) inAxfr(q *Msg, c chan *Envelope) {
}
func (t *Transfer) inIxfr(q *Msg, c chan *Envelope) {
serial := uint32(0) // The first serial seen is the current server serial
var serial uint32 // The first serial seen is the current server serial
axfr := true
n := 0
qser := q.Ns[0].(*SOA).Serial
......@@ -176,14 +193,17 @@ func (t *Transfer) inIxfr(q *Msg, c chan *Envelope) {
//
// ch := make(chan *dns.Envelope)
// tr := new(dns.Transfer)
// go tr.Out(w, r, ch)
// var wg sync.WaitGroup
// go func() {
// tr.Out(w, r, ch)
// wg.Done()
// }()
// ch <- &dns.Envelope{RR: []dns.RR{soa, rr1, rr2, rr3, soa}}
// close(ch)
// w.Hijack()
// // w.Close() // Client closes connection
// wg.Wait() // wait until everything is written out
// w.Close() // close connection
//
// The server is responsible for sending the correct sequence of RRs through the
// channel ch.
// The server is responsible for sending the correct sequence of RRs through the channel ch.
func (t *Transfer) Out(w ResponseWriter, q *Msg, ch chan *Envelope) error {
for x := range ch {
r := new(Msg)
......@@ -192,11 +212,14 @@ func (t *Transfer) Out(w ResponseWriter, q *Msg, ch chan *Envelope) error {
r.Authoritative = true
// assume it fits TODO(miek): fix
r.Answer = append(r.Answer, x.RR...)
if tsig := q.IsTsig(); tsig != nil && w.TsigStatus() == nil {
r.SetTsig(tsig.Hdr.Name, tsig.Algorithm, tsig.Fudge, time.Now().Unix())
}
if err := w.WriteMsg(r); err != nil {
return err
}
}
w.TsigTimersOnly(true)
}
return nil
}
......@@ -212,12 +235,9 @@ func (t *Transfer) ReadMsg() (*Msg, error) {
if err := m.Unpack(p); err != nil {
return nil, err
}
if ts := m.IsTsig(); ts != nil && t.TsigSecret != nil {
if _, ok := t.TsigSecret[ts.Hdr.Name]; !ok {
return m, ErrSecret
}
if ts, tp := m.IsTsig(), t.tsigProvider(); ts != nil && tp != nil {
// Need to work on the original message p, as that was used to calculate the tsig.
err = TsigVerify(p, t.TsigSecret[ts.Hdr.Name], t.tsigRequestMAC, t.tsigTimersOnly)
err = TsigVerifyWithProvider(p, tp, t.tsigRequestMAC, t.tsigTimersOnly)
t.tsigRequestMAC = ts.MAC
}
return m, err
......@@ -226,35 +246,26 @@ func (t *Transfer) ReadMsg() (*Msg, error) {
// WriteMsg writes a message through the transfer connection t.
func (t *Transfer) WriteMsg(m *Msg) (err error) {
var out []byte
if ts := m.IsTsig(); ts != nil && t.TsigSecret != nil {
if _, ok := t.TsigSecret[ts.Hdr.Name]; !ok {
return ErrSecret
}
out, t.tsigRequestMAC, err = TsigGenerate(m, t.TsigSecret[ts.Hdr.Name], t.tsigRequestMAC, t.tsigTimersOnly)
if ts, tp := m.IsTsig(), t.tsigProvider(); ts != nil && tp != nil {
out, t.tsigRequestMAC, err = TsigGenerateWithProvider(m, tp, t.tsigRequestMAC, t.tsigTimersOnly)
} else {
out, err = m.Pack()
}
if err != nil {
return err
}
if _, err = t.Write(out); err != nil {
_, err = t.Write(out)
return err
}
return nil
}
func isSOAFirst(in *Msg) bool {
if len(in.Answer) > 0 {
return in.Answer[0].Header().Rrtype == TypeSOA
}
return false
return len(in.Answer) > 0 &&
in.Answer[0].Header().Rrtype == TypeSOA
}
func isSOALast(in *Msg) bool {
if len(in.Answer) > 0 {
return in.Answer[len(in.Answer)-1].Header().Rrtype == TypeSOA
}
return false
return len(in.Answer) > 0 &&
in.Answer[len(in.Answer)-1].Header().Rrtype == TypeSOA
}
const errXFR = "bad xfr rcode: %d"
// Code generated by "go run compress_generate.go"; DO NOT EDIT.
package dns
func compressionLenHelperType(c map[string]int, r RR, initLen int) int {
currentLen := initLen
switch x := r.(type) {
case *AFSDB:
currentLen -= len(x.Hostname) + 1
currentLen += compressionLenHelper(c, x.Hostname, currentLen)
case *CNAME:
currentLen -= len(x.Target) + 1
currentLen += compressionLenHelper(c, x.Target, currentLen)
case *DNAME:
currentLen -= len(x.Target) + 1
currentLen += compressionLenHelper(c, x.Target, currentLen)
case *HIP:
for i := range x.RendezvousServers {
currentLen -= len(x.RendezvousServers[i]) + 1
}
for i := range x.RendezvousServers {
currentLen += compressionLenHelper(c, x.RendezvousServers[i], currentLen)
}
case *KX:
currentLen -= len(x.Exchanger) + 1
currentLen += compressionLenHelper(c, x.Exchanger, currentLen)
case *LP:
currentLen -= len(x.Fqdn) + 1
currentLen += compressionLenHelper(c, x.Fqdn, currentLen)
case *MB:
currentLen -= len(x.Mb) + 1
currentLen += compressionLenHelper(c, x.Mb, currentLen)
case *MD:
currentLen -= len(x.Md) + 1
currentLen += compressionLenHelper(c, x.Md, currentLen)
case *MF:
currentLen -= len(x.Mf) + 1
currentLen += compressionLenHelper(c, x.Mf, currentLen)
case *MG:
currentLen -= len(x.Mg) + 1
currentLen += compressionLenHelper(c, x.Mg, currentLen)
case *MINFO:
currentLen -= len(x.Rmail) + 1
currentLen += compressionLenHelper(c, x.Rmail, currentLen)
currentLen -= len(x.Email) + 1
currentLen += compressionLenHelper(c, x.Email, currentLen)
case *MR:
currentLen -= len(x.Mr) + 1
currentLen += compressionLenHelper(c, x.Mr, currentLen)
case *MX:
currentLen -= len(x.Mx) + 1
currentLen += compressionLenHelper(c, x.Mx, currentLen)
case *NAPTR:
currentLen -= len(x.Replacement) + 1
currentLen += compressionLenHelper(c, x.Replacement, currentLen)
case *NS:
currentLen -= len(x.Ns) + 1
currentLen += compressionLenHelper(c, x.Ns, currentLen)
case *NSAPPTR:
currentLen -= len(x.Ptr) + 1
currentLen += compressionLenHelper(c, x.Ptr, currentLen)
case *NSEC:
currentLen -= len(x.NextDomain) + 1
currentLen += compressionLenHelper(c, x.NextDomain, currentLen)
case *PTR:
currentLen -= len(x.Ptr) + 1
currentLen += compressionLenHelper(c, x.Ptr, currentLen)
case *PX:
currentLen -= len(x.Map822) + 1
currentLen += compressionLenHelper(c, x.Map822, currentLen)
currentLen -= len(x.Mapx400) + 1
currentLen += compressionLenHelper(c, x.Mapx400, currentLen)
case *RP:
currentLen -= len(x.Mbox) + 1
currentLen += compressionLenHelper(c, x.Mbox, currentLen)
currentLen -= len(x.Txt) + 1
currentLen += compressionLenHelper(c, x.Txt, currentLen)
case *RRSIG:
currentLen -= len(x.SignerName) + 1
currentLen += compressionLenHelper(c, x.SignerName, currentLen)
case *RT:
currentLen -= len(x.Host) + 1
currentLen += compressionLenHelper(c, x.Host, currentLen)
case *SIG:
currentLen -= len(x.SignerName) + 1
currentLen += compressionLenHelper(c, x.SignerName, currentLen)
case *SOA:
currentLen -= len(x.Ns) + 1
currentLen += compressionLenHelper(c, x.Ns, currentLen)
currentLen -= len(x.Mbox) + 1
currentLen += compressionLenHelper(c, x.Mbox, currentLen)
case *SRV:
currentLen -= len(x.Target) + 1
currentLen += compressionLenHelper(c, x.Target, currentLen)
case *TALINK:
currentLen -= len(x.PreviousName) + 1
currentLen += compressionLenHelper(c, x.PreviousName, currentLen)
currentLen -= len(x.NextName) + 1
currentLen += compressionLenHelper(c, x.NextName, currentLen)
case *TKEY:
currentLen -= len(x.Algorithm) + 1
currentLen += compressionLenHelper(c, x.Algorithm, currentLen)
case *TSIG:
currentLen -= len(x.Algorithm) + 1
currentLen += compressionLenHelper(c, x.Algorithm, currentLen)
}
return currentLen - initLen
}
func compressionLenSearchType(c map[string]int, r RR) (int, bool, int) {
switch x := r.(type) {
case *CNAME:
k1, ok1, sz1 := compressionLenSearch(c, x.Target)
return k1, ok1, sz1
case *MB:
k1, ok1, sz1 := compressionLenSearch(c, x.Mb)
return k1, ok1, sz1
case *MD:
k1, ok1, sz1 := compressionLenSearch(c, x.Md)
return k1, ok1, sz1
case *MF:
k1, ok1, sz1 := compressionLenSearch(c, x.Mf)
return k1, ok1, sz1
case *MG:
k1, ok1, sz1 := compressionLenSearch(c, x.Mg)
return k1, ok1, sz1
case *MINFO:
k1, ok1, sz1 := compressionLenSearch(c, x.Rmail)
k2, ok2, sz2 := compressionLenSearch(c, x.Email)
return k1 + k2, ok1 && ok2, sz1 + sz2
case *MR:
k1, ok1, sz1 := compressionLenSearch(c, x.Mr)
return k1, ok1, sz1
case *MX:
k1, ok1, sz1 := compressionLenSearch(c, x.Mx)
return k1, ok1, sz1
case *NS:
k1, ok1, sz1 := compressionLenSearch(c, x.Ns)
return k1, ok1, sz1
case *PTR:
k1, ok1, sz1 := compressionLenSearch(c, x.Ptr)
return k1, ok1, sz1
case *RT:
k1, ok1, sz1 := compressionLenSearch(c, x.Host)
return k1, ok1, sz1
case *SOA:
k1, ok1, sz1 := compressionLenSearch(c, x.Ns)
k2, ok2, sz2 := compressionLenSearch(c, x.Mbox)
return k1 + k2, ok1 && ok2, sz1 + sz2
}
return 0, false, 0
}
......@@ -2,174 +2,79 @@
package dns
// isDuplicateRdata calls the rdata specific functions
func isDuplicateRdata(r1, r2 RR) bool {
switch r1.Header().Rrtype {
case TypeA:
return isDuplicateA(r1.(*A), r2.(*A))
case TypeAAAA:
return isDuplicateAAAA(r1.(*AAAA), r2.(*AAAA))
case TypeAFSDB:
return isDuplicateAFSDB(r1.(*AFSDB), r2.(*AFSDB))
case TypeAVC:
return isDuplicateAVC(r1.(*AVC), r2.(*AVC))
case TypeCAA:
return isDuplicateCAA(r1.(*CAA), r2.(*CAA))
case TypeCERT:
return isDuplicateCERT(r1.(*CERT), r2.(*CERT))
case TypeCNAME:
return isDuplicateCNAME(r1.(*CNAME), r2.(*CNAME))
case TypeCSYNC:
return isDuplicateCSYNC(r1.(*CSYNC), r2.(*CSYNC))
case TypeDHCID:
return isDuplicateDHCID(r1.(*DHCID), r2.(*DHCID))
case TypeDNAME:
return isDuplicateDNAME(r1.(*DNAME), r2.(*DNAME))
case TypeDNSKEY:
return isDuplicateDNSKEY(r1.(*DNSKEY), r2.(*DNSKEY))
case TypeDS:
return isDuplicateDS(r1.(*DS), r2.(*DS))
case TypeEID:
return isDuplicateEID(r1.(*EID), r2.(*EID))
case TypeEUI48:
return isDuplicateEUI48(r1.(*EUI48), r2.(*EUI48))
case TypeEUI64:
return isDuplicateEUI64(r1.(*EUI64), r2.(*EUI64))
case TypeGID:
return isDuplicateGID(r1.(*GID), r2.(*GID))
case TypeGPOS:
return isDuplicateGPOS(r1.(*GPOS), r2.(*GPOS))
case TypeHINFO:
return isDuplicateHINFO(r1.(*HINFO), r2.(*HINFO))
case TypeHIP:
return isDuplicateHIP(r1.(*HIP), r2.(*HIP))
case TypeKX:
return isDuplicateKX(r1.(*KX), r2.(*KX))
case TypeL32:
return isDuplicateL32(r1.(*L32), r2.(*L32))
case TypeL64:
return isDuplicateL64(r1.(*L64), r2.(*L64))
case TypeLOC:
return isDuplicateLOC(r1.(*LOC), r2.(*LOC))
case TypeLP:
return isDuplicateLP(r1.(*LP), r2.(*LP))
case TypeMB:
return isDuplicateMB(r1.(*MB), r2.(*MB))
case TypeMD:
return isDuplicateMD(r1.(*MD), r2.(*MD))
case TypeMF:
return isDuplicateMF(r1.(*MF), r2.(*MF))
case TypeMG:
return isDuplicateMG(r1.(*MG), r2.(*MG))
case TypeMINFO:
return isDuplicateMINFO(r1.(*MINFO), r2.(*MINFO))
case TypeMR:
return isDuplicateMR(r1.(*MR), r2.(*MR))
case TypeMX:
return isDuplicateMX(r1.(*MX), r2.(*MX))
case TypeNAPTR:
return isDuplicateNAPTR(r1.(*NAPTR), r2.(*NAPTR))
case TypeNID:
return isDuplicateNID(r1.(*NID), r2.(*NID))
case TypeNIMLOC:
return isDuplicateNIMLOC(r1.(*NIMLOC), r2.(*NIMLOC))
case TypeNINFO:
return isDuplicateNINFO(r1.(*NINFO), r2.(*NINFO))
case TypeNS:
return isDuplicateNS(r1.(*NS), r2.(*NS))
case TypeNSAPPTR:
return isDuplicateNSAPPTR(r1.(*NSAPPTR), r2.(*NSAPPTR))
case TypeNSEC:
return isDuplicateNSEC(r1.(*NSEC), r2.(*NSEC))
case TypeNSEC3:
return isDuplicateNSEC3(r1.(*NSEC3), r2.(*NSEC3))
case TypeNSEC3PARAM:
return isDuplicateNSEC3PARAM(r1.(*NSEC3PARAM), r2.(*NSEC3PARAM))
case TypeOPENPGPKEY:
return isDuplicateOPENPGPKEY(r1.(*OPENPGPKEY), r2.(*OPENPGPKEY))
case TypePTR:
return isDuplicatePTR(r1.(*PTR), r2.(*PTR))
case TypePX:
return isDuplicatePX(r1.(*PX), r2.(*PX))
case TypeRKEY:
return isDuplicateRKEY(r1.(*RKEY), r2.(*RKEY))
case TypeRP:
return isDuplicateRP(r1.(*RP), r2.(*RP))
case TypeRRSIG:
return isDuplicateRRSIG(r1.(*RRSIG), r2.(*RRSIG))
case TypeRT:
return isDuplicateRT(r1.(*RT), r2.(*RT))
case TypeSMIMEA:
return isDuplicateSMIMEA(r1.(*SMIMEA), r2.(*SMIMEA))
case TypeSOA:
return isDuplicateSOA(r1.(*SOA), r2.(*SOA))
case TypeSPF:
return isDuplicateSPF(r1.(*SPF), r2.(*SPF))
case TypeSRV:
return isDuplicateSRV(r1.(*SRV), r2.(*SRV))
case TypeSSHFP:
return isDuplicateSSHFP(r1.(*SSHFP), r2.(*SSHFP))
case TypeTA:
return isDuplicateTA(r1.(*TA), r2.(*TA))
case TypeTALINK:
return isDuplicateTALINK(r1.(*TALINK), r2.(*TALINK))
case TypeTKEY:
return isDuplicateTKEY(r1.(*TKEY), r2.(*TKEY))
case TypeTLSA:
return isDuplicateTLSA(r1.(*TLSA), r2.(*TLSA))
case TypeTSIG:
return isDuplicateTSIG(r1.(*TSIG), r2.(*TSIG))
case TypeTXT:
return isDuplicateTXT(r1.(*TXT), r2.(*TXT))
case TypeUID:
return isDuplicateUID(r1.(*UID), r2.(*UID))
case TypeUINFO:
return isDuplicateUINFO(r1.(*UINFO), r2.(*UINFO))
case TypeURI:
return isDuplicateURI(r1.(*URI), r2.(*URI))
case TypeX25:
return isDuplicateX25(r1.(*X25), r2.(*X25))
// isDuplicate() functions
func (r1 *A) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*A)
if !ok {
return false
}
_ = r2
if !r1.A.Equal(r2.A) {
return false
}
return true
}
// isDuplicate() functions
func isDuplicateA(r1, r2 *A) bool {
if len(r1.A) != len(r2.A) {
func (r1 *AAAA) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*AAAA)
if !ok {
return false
}
for i := 0; i < len(r1.A); i++ {
if r1.A[i] != r2.A[i] {
_ = r2
if !r1.AAAA.Equal(r2.AAAA) {
return false
}
}
return true
}
func isDuplicateAAAA(r1, r2 *AAAA) bool {
if len(r1.AAAA) != len(r2.AAAA) {
func (r1 *AFSDB) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*AFSDB)
if !ok {
return false
}
for i := 0; i < len(r1.AAAA); i++ {
if r1.AAAA[i] != r2.AAAA[i] {
_ = r2
if r1.Subtype != r2.Subtype {
return false
}
if !isDuplicateName(r1.Hostname, r2.Hostname) {
return false
}
return true
}
func isDuplicateAFSDB(r1, r2 *AFSDB) bool {
if r1.Subtype != r2.Subtype {
func (r1 *ANY) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*ANY)
if !ok {
return false
}
if !isDulicateName(r1.Hostname, r2.Hostname) {
_ = r2
return true
}
func (r1 *APL) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*APL)
if !ok {
return false
}
_ = r2
if len(r1.Prefixes) != len(r2.Prefixes) {
return false
}
for i := 0; i < len(r1.Prefixes); i++ {
if !r1.Prefixes[i].equals(&r2.Prefixes[i]) {
return false
}
}
return true
}
func isDuplicateAVC(r1, r2 *AVC) bool {
func (r1 *AVC) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*AVC)
if !ok {
return false
}
_ = r2
if len(r1.Txt) != len(r2.Txt) {
return false
}
......@@ -181,7 +86,12 @@ func isDuplicateAVC(r1, r2 *AVC) bool {
return true
}
func isDuplicateCAA(r1, r2 *CAA) bool {
func (r1 *CAA) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*CAA)
if !ok {
return false
}
_ = r2
if r1.Flag != r2.Flag {
return false
}
......@@ -194,7 +104,54 @@ func isDuplicateCAA(r1, r2 *CAA) bool {
return true
}
func isDuplicateCERT(r1, r2 *CERT) bool {
func (r1 *CDNSKEY) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*CDNSKEY)
if !ok {
return false
}
_ = r2
if r1.Flags != r2.Flags {
return false
}
if r1.Protocol != r2.Protocol {
return false
}
if r1.Algorithm != r2.Algorithm {
return false
}
if r1.PublicKey != r2.PublicKey {
return false
}
return true
}
func (r1 *CDS) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*CDS)
if !ok {
return false
}
_ = r2
if r1.KeyTag != r2.KeyTag {
return false
}
if r1.Algorithm != r2.Algorithm {
return false
}
if r1.DigestType != r2.DigestType {
return false
}
if r1.Digest != r2.Digest {
return false
}
return true
}
func (r1 *CERT) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*CERT)
if !ok {
return false
}
_ = r2
if r1.Type != r2.Type {
return false
}
......@@ -210,14 +167,24 @@ func isDuplicateCERT(r1, r2 *CERT) bool {
return true
}
func isDuplicateCNAME(r1, r2 *CNAME) bool {
if !isDulicateName(r1.Target, r2.Target) {
func (r1 *CNAME) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*CNAME)
if !ok {
return false
}
_ = r2
if !isDuplicateName(r1.Target, r2.Target) {
return false
}
return true
}
func isDuplicateCSYNC(r1, r2 *CSYNC) bool {
func (r1 *CSYNC) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*CSYNC)
if !ok {
return false
}
_ = r2
if r1.Serial != r2.Serial {
return false
}
......@@ -235,21 +202,57 @@ func isDuplicateCSYNC(r1, r2 *CSYNC) bool {
return true
}
func isDuplicateDHCID(r1, r2 *DHCID) bool {
func (r1 *DHCID) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*DHCID)
if !ok {
return false
}
_ = r2
if r1.Digest != r2.Digest {
return false
}
return true
}
func isDuplicateDNAME(r1, r2 *DNAME) bool {
if !isDulicateName(r1.Target, r2.Target) {
func (r1 *DLV) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*DLV)
if !ok {
return false
}
_ = r2
if r1.KeyTag != r2.KeyTag {
return false
}
if r1.Algorithm != r2.Algorithm {
return false
}
if r1.DigestType != r2.DigestType {
return false
}
if r1.Digest != r2.Digest {
return false
}
return true
}
func (r1 *DNAME) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*DNAME)
if !ok {
return false
}
_ = r2
if !isDuplicateName(r1.Target, r2.Target) {
return false
}
return true
}
func isDuplicateDNSKEY(r1, r2 *DNSKEY) bool {
func (r1 *DNSKEY) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*DNSKEY)
if !ok {
return false
}
_ = r2
if r1.Flags != r2.Flags {
return false
}
......@@ -265,7 +268,12 @@ func isDuplicateDNSKEY(r1, r2 *DNSKEY) bool {
return true
}
func isDuplicateDS(r1, r2 *DS) bool {
func (r1 *DS) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*DS)
if !ok {
return false
}
_ = r2
if r1.KeyTag != r2.KeyTag {
return false
}
......@@ -281,35 +289,60 @@ func isDuplicateDS(r1, r2 *DS) bool {
return true
}
func isDuplicateEID(r1, r2 *EID) bool {
func (r1 *EID) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*EID)
if !ok {
return false
}
_ = r2
if r1.Endpoint != r2.Endpoint {
return false
}
return true
}
func isDuplicateEUI48(r1, r2 *EUI48) bool {
func (r1 *EUI48) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*EUI48)
if !ok {
return false
}
_ = r2
if r1.Address != r2.Address {
return false
}
return true
}
func isDuplicateEUI64(r1, r2 *EUI64) bool {
func (r1 *EUI64) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*EUI64)
if !ok {
return false
}
_ = r2
if r1.Address != r2.Address {
return false
}
return true
}
func isDuplicateGID(r1, r2 *GID) bool {
func (r1 *GID) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*GID)
if !ok {
return false
}
_ = r2
if r1.Gid != r2.Gid {
return false
}
return true
}
func isDuplicateGPOS(r1, r2 *GPOS) bool {
func (r1 *GPOS) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*GPOS)
if !ok {
return false
}
_ = r2
if r1.Longitude != r2.Longitude {
return false
}
......@@ -322,7 +355,12 @@ func isDuplicateGPOS(r1, r2 *GPOS) bool {
return true
}
func isDuplicateHINFO(r1, r2 *HINFO) bool {
func (r1 *HINFO) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*HINFO)
if !ok {
return false
}
_ = r2
if r1.Cpu != r2.Cpu {
return false
}
......@@ -332,7 +370,12 @@ func isDuplicateHINFO(r1, r2 *HINFO) bool {
return true
}
func isDuplicateHIP(r1, r2 *HIP) bool {
func (r1 *HIP) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*HIP)
if !ok {
return false
}
_ = r2
if r1.HitLength != r2.HitLength {
return false
}
......@@ -352,39 +395,91 @@ func isDuplicateHIP(r1, r2 *HIP) bool {
return false
}
for i := 0; i < len(r1.RendezvousServers); i++ {
if !isDulicateName(r1.RendezvousServers[i], r2.RendezvousServers[i]) {
if !isDuplicateName(r1.RendezvousServers[i], r2.RendezvousServers[i]) {
return false
}
}
return true
}
func isDuplicateKX(r1, r2 *KX) bool {
if r1.Preference != r2.Preference {
func (r1 *HTTPS) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*HTTPS)
if !ok {
return false
}
if !isDulicateName(r1.Exchanger, r2.Exchanger) {
_ = r2
if r1.Priority != r2.Priority {
return false
}
if !isDuplicateName(r1.Target, r2.Target) {
return false
}
if len(r1.Value) != len(r2.Value) {
return false
}
if !areSVCBPairArraysEqual(r1.Value, r2.Value) {
return false
}
return true
}
func isDuplicateL32(r1, r2 *L32) bool {
func (r1 *KEY) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*KEY)
if !ok {
return false
}
_ = r2
if r1.Flags != r2.Flags {
return false
}
if r1.Protocol != r2.Protocol {
return false
}
if r1.Algorithm != r2.Algorithm {
return false
}
if r1.PublicKey != r2.PublicKey {
return false
}
return true
}
func (r1 *KX) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*KX)
if !ok {
return false
}
_ = r2
if r1.Preference != r2.Preference {
return false
}
if len(r1.Locator32) != len(r2.Locator32) {
if !isDuplicateName(r1.Exchanger, r2.Exchanger) {
return false
}
for i := 0; i < len(r1.Locator32); i++ {
if r1.Locator32[i] != r2.Locator32[i] {
return true
}
func (r1 *L32) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*L32)
if !ok {
return false
}
_ = r2
if r1.Preference != r2.Preference {
return false
}
if !r1.Locator32.Equal(r2.Locator32) {
return false
}
return true
}
func isDuplicateL64(r1, r2 *L64) bool {
func (r1 *L64) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*L64)
if !ok {
return false
}
_ = r2
if r1.Preference != r2.Preference {
return false
}
......@@ -394,7 +489,12 @@ func isDuplicateL64(r1, r2 *L64) bool {
return true
}
func isDuplicateLOC(r1, r2 *LOC) bool {
func (r1 *LOC) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*LOC)
if !ok {
return false
}
_ = r2
if r1.Version != r2.Version {
return false
}
......@@ -419,72 +519,117 @@ func isDuplicateLOC(r1, r2 *LOC) bool {
return true
}
func isDuplicateLP(r1, r2 *LP) bool {
func (r1 *LP) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*LP)
if !ok {
return false
}
_ = r2
if r1.Preference != r2.Preference {
return false
}
if !isDulicateName(r1.Fqdn, r2.Fqdn) {
if !isDuplicateName(r1.Fqdn, r2.Fqdn) {
return false
}
return true
}
func isDuplicateMB(r1, r2 *MB) bool {
if !isDulicateName(r1.Mb, r2.Mb) {
func (r1 *MB) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*MB)
if !ok {
return false
}
_ = r2
if !isDuplicateName(r1.Mb, r2.Mb) {
return false
}
return true
}
func isDuplicateMD(r1, r2 *MD) bool {
if !isDulicateName(r1.Md, r2.Md) {
func (r1 *MD) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*MD)
if !ok {
return false
}
_ = r2
if !isDuplicateName(r1.Md, r2.Md) {
return false
}
return true
}
func isDuplicateMF(r1, r2 *MF) bool {
if !isDulicateName(r1.Mf, r2.Mf) {
func (r1 *MF) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*MF)
if !ok {
return false
}
_ = r2
if !isDuplicateName(r1.Mf, r2.Mf) {
return false
}
return true
}
func isDuplicateMG(r1, r2 *MG) bool {
if !isDulicateName(r1.Mg, r2.Mg) {
func (r1 *MG) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*MG)
if !ok {
return false
}
_ = r2
if !isDuplicateName(r1.Mg, r2.Mg) {
return false
}
return true
}
func isDuplicateMINFO(r1, r2 *MINFO) bool {
if !isDulicateName(r1.Rmail, r2.Rmail) {
func (r1 *MINFO) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*MINFO)
if !ok {
return false
}
_ = r2
if !isDuplicateName(r1.Rmail, r2.Rmail) {
return false
}
if !isDulicateName(r1.Email, r2.Email) {
if !isDuplicateName(r1.Email, r2.Email) {
return false
}
return true
}
func isDuplicateMR(r1, r2 *MR) bool {
if !isDulicateName(r1.Mr, r2.Mr) {
func (r1 *MR) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*MR)
if !ok {
return false
}
_ = r2
if !isDuplicateName(r1.Mr, r2.Mr) {
return false
}
return true
}
func isDuplicateMX(r1, r2 *MX) bool {
func (r1 *MX) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*MX)
if !ok {
return false
}
_ = r2
if r1.Preference != r2.Preference {
return false
}
if !isDulicateName(r1.Mx, r2.Mx) {
if !isDuplicateName(r1.Mx, r2.Mx) {
return false
}
return true
}
func isDuplicateNAPTR(r1, r2 *NAPTR) bool {
func (r1 *NAPTR) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*NAPTR)
if !ok {
return false
}
_ = r2
if r1.Order != r2.Order {
return false
}
......@@ -500,13 +645,18 @@ func isDuplicateNAPTR(r1, r2 *NAPTR) bool {
if r1.Regexp != r2.Regexp {
return false
}
if !isDulicateName(r1.Replacement, r2.Replacement) {
if !isDuplicateName(r1.Replacement, r2.Replacement) {
return false
}
return true
}
func isDuplicateNID(r1, r2 *NID) bool {
func (r1 *NID) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*NID)
if !ok {
return false
}
_ = r2
if r1.Preference != r2.Preference {
return false
}
......@@ -516,14 +666,24 @@ func isDuplicateNID(r1, r2 *NID) bool {
return true
}
func isDuplicateNIMLOC(r1, r2 *NIMLOC) bool {
func (r1 *NIMLOC) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*NIMLOC)
if !ok {
return false
}
_ = r2
if r1.Locator != r2.Locator {
return false
}
return true
}
func isDuplicateNINFO(r1, r2 *NINFO) bool {
func (r1 *NINFO) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*NINFO)
if !ok {
return false
}
_ = r2
if len(r1.ZSData) != len(r2.ZSData) {
return false
}
......@@ -535,22 +695,37 @@ func isDuplicateNINFO(r1, r2 *NINFO) bool {
return true
}
func isDuplicateNS(r1, r2 *NS) bool {
if !isDulicateName(r1.Ns, r2.Ns) {
func (r1 *NS) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*NS)
if !ok {
return false
}
_ = r2
if !isDuplicateName(r1.Ns, r2.Ns) {
return false
}
return true
}
func isDuplicateNSAPPTR(r1, r2 *NSAPPTR) bool {
if !isDulicateName(r1.Ptr, r2.Ptr) {
func (r1 *NSAPPTR) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*NSAPPTR)
if !ok {
return false
}
_ = r2
if !isDuplicateName(r1.Ptr, r2.Ptr) {
return false
}
return true
}
func isDuplicateNSEC(r1, r2 *NSEC) bool {
if !isDulicateName(r1.NextDomain, r2.NextDomain) {
func (r1 *NSEC) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*NSEC)
if !ok {
return false
}
_ = r2
if !isDuplicateName(r1.NextDomain, r2.NextDomain) {
return false
}
if len(r1.TypeBitMap) != len(r2.TypeBitMap) {
......@@ -564,7 +739,12 @@ func isDuplicateNSEC(r1, r2 *NSEC) bool {
return true
}
func isDuplicateNSEC3(r1, r2 *NSEC3) bool {
func (r1 *NSEC3) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*NSEC3)
if !ok {
return false
}
_ = r2
if r1.Hash != r2.Hash {
return false
}
......@@ -597,7 +777,12 @@ func isDuplicateNSEC3(r1, r2 *NSEC3) bool {
return true
}
func isDuplicateNSEC3PARAM(r1, r2 *NSEC3PARAM) bool {
func (r1 *NSEC3PARAM) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*NSEC3PARAM)
if !ok {
return false
}
_ = r2
if r1.Hash != r2.Hash {
return false
}
......@@ -616,34 +801,78 @@ func isDuplicateNSEC3PARAM(r1, r2 *NSEC3PARAM) bool {
return true
}
func isDuplicateOPENPGPKEY(r1, r2 *OPENPGPKEY) bool {
func (r1 *NULL) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*NULL)
if !ok {
return false
}
_ = r2
if r1.Data != r2.Data {
return false
}
return true
}
func (r1 *OPENPGPKEY) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*OPENPGPKEY)
if !ok {
return false
}
_ = r2
if r1.PublicKey != r2.PublicKey {
return false
}
return true
}
func isDuplicatePTR(r1, r2 *PTR) bool {
if !isDulicateName(r1.Ptr, r2.Ptr) {
func (r1 *PTR) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*PTR)
if !ok {
return false
}
_ = r2
if !isDuplicateName(r1.Ptr, r2.Ptr) {
return false
}
return true
}
func isDuplicatePX(r1, r2 *PX) bool {
func (r1 *PX) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*PX)
if !ok {
return false
}
_ = r2
if r1.Preference != r2.Preference {
return false
}
if !isDulicateName(r1.Map822, r2.Map822) {
if !isDuplicateName(r1.Map822, r2.Map822) {
return false
}
if !isDuplicateName(r1.Mapx400, r2.Mapx400) {
return false
}
return true
}
func (r1 *RFC3597) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*RFC3597)
if !ok {
return false
}
if !isDulicateName(r1.Mapx400, r2.Mapx400) {
_ = r2
if r1.Rdata != r2.Rdata {
return false
}
return true
}
func isDuplicateRKEY(r1, r2 *RKEY) bool {
func (r1 *RKEY) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*RKEY)
if !ok {
return false
}
_ = r2
if r1.Flags != r2.Flags {
return false
}
......@@ -659,17 +888,27 @@ func isDuplicateRKEY(r1, r2 *RKEY) bool {
return true
}
func isDuplicateRP(r1, r2 *RP) bool {
if !isDulicateName(r1.Mbox, r2.Mbox) {
func (r1 *RP) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*RP)
if !ok {
return false
}
_ = r2
if !isDuplicateName(r1.Mbox, r2.Mbox) {
return false
}
if !isDulicateName(r1.Txt, r2.Txt) {
if !isDuplicateName(r1.Txt, r2.Txt) {
return false
}
return true
}
func isDuplicateRRSIG(r1, r2 *RRSIG) bool {
func (r1 *RRSIG) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*RRSIG)
if !ok {
return false
}
_ = r2
if r1.TypeCovered != r2.TypeCovered {
return false
}
......@@ -691,7 +930,7 @@ func isDuplicateRRSIG(r1, r2 *RRSIG) bool {
if r1.KeyTag != r2.KeyTag {
return false
}
if !isDulicateName(r1.SignerName, r2.SignerName) {
if !isDuplicateName(r1.SignerName, r2.SignerName) {
return false
}
if r1.Signature != r2.Signature {
......@@ -700,17 +939,63 @@ func isDuplicateRRSIG(r1, r2 *RRSIG) bool {
return true
}
func isDuplicateRT(r1, r2 *RT) bool {
func (r1 *RT) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*RT)
if !ok {
return false
}
_ = r2
if r1.Preference != r2.Preference {
return false
}
if !isDulicateName(r1.Host, r2.Host) {
if !isDuplicateName(r1.Host, r2.Host) {
return false
}
return true
}
func (r1 *SIG) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*SIG)
if !ok {
return false
}
_ = r2
if r1.TypeCovered != r2.TypeCovered {
return false
}
if r1.Algorithm != r2.Algorithm {
return false
}
if r1.Labels != r2.Labels {
return false
}
if r1.OrigTtl != r2.OrigTtl {
return false
}
if r1.Expiration != r2.Expiration {
return false
}
if r1.Inception != r2.Inception {
return false
}
if r1.KeyTag != r2.KeyTag {
return false
}
if !isDuplicateName(r1.SignerName, r2.SignerName) {
return false
}
if r1.Signature != r2.Signature {
return false
}
return true
}
func isDuplicateSMIMEA(r1, r2 *SMIMEA) bool {
func (r1 *SMIMEA) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*SMIMEA)
if !ok {
return false
}
_ = r2
if r1.Usage != r2.Usage {
return false
}
......@@ -726,11 +1011,16 @@ func isDuplicateSMIMEA(r1, r2 *SMIMEA) bool {
return true
}
func isDuplicateSOA(r1, r2 *SOA) bool {
if !isDulicateName(r1.Ns, r2.Ns) {
func (r1 *SOA) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*SOA)
if !ok {
return false
}
if !isDulicateName(r1.Mbox, r2.Mbox) {
_ = r2
if !isDuplicateName(r1.Ns, r2.Ns) {
return false
}
if !isDuplicateName(r1.Mbox, r2.Mbox) {
return false
}
if r1.Serial != r2.Serial {
......@@ -751,7 +1041,12 @@ func isDuplicateSOA(r1, r2 *SOA) bool {
return true
}
func isDuplicateSPF(r1, r2 *SPF) bool {
func (r1 *SPF) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*SPF)
if !ok {
return false
}
_ = r2
if len(r1.Txt) != len(r2.Txt) {
return false
}
......@@ -763,7 +1058,12 @@ func isDuplicateSPF(r1, r2 *SPF) bool {
return true
}
func isDuplicateSRV(r1, r2 *SRV) bool {
func (r1 *SRV) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*SRV)
if !ok {
return false
}
_ = r2
if r1.Priority != r2.Priority {
return false
}
......@@ -773,13 +1073,18 @@ func isDuplicateSRV(r1, r2 *SRV) bool {
if r1.Port != r2.Port {
return false
}
if !isDulicateName(r1.Target, r2.Target) {
if !isDuplicateName(r1.Target, r2.Target) {
return false
}
return true
}
func isDuplicateSSHFP(r1, r2 *SSHFP) bool {
func (r1 *SSHFP) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*SSHFP)
if !ok {
return false
}
_ = r2
if r1.Algorithm != r2.Algorithm {
return false
}
......@@ -792,7 +1097,33 @@ func isDuplicateSSHFP(r1, r2 *SSHFP) bool {
return true
}
func isDuplicateTA(r1, r2 *TA) bool {
func (r1 *SVCB) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*SVCB)
if !ok {
return false
}
_ = r2
if r1.Priority != r2.Priority {
return false
}
if !isDuplicateName(r1.Target, r2.Target) {
return false
}
if len(r1.Value) != len(r2.Value) {
return false
}
if !areSVCBPairArraysEqual(r1.Value, r2.Value) {
return false
}
return true
}
func (r1 *TA) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*TA)
if !ok {
return false
}
_ = r2
if r1.KeyTag != r2.KeyTag {
return false
}
......@@ -808,18 +1139,28 @@ func isDuplicateTA(r1, r2 *TA) bool {
return true
}
func isDuplicateTALINK(r1, r2 *TALINK) bool {
if !isDulicateName(r1.PreviousName, r2.PreviousName) {
func (r1 *TALINK) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*TALINK)
if !ok {
return false
}
if !isDulicateName(r1.NextName, r2.NextName) {
_ = r2
if !isDuplicateName(r1.PreviousName, r2.PreviousName) {
return false
}
if !isDuplicateName(r1.NextName, r2.NextName) {
return false
}
return true
}
func isDuplicateTKEY(r1, r2 *TKEY) bool {
if !isDulicateName(r1.Algorithm, r2.Algorithm) {
func (r1 *TKEY) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*TKEY)
if !ok {
return false
}
_ = r2
if !isDuplicateName(r1.Algorithm, r2.Algorithm) {
return false
}
if r1.Inception != r2.Inception {
......@@ -849,7 +1190,12 @@ func isDuplicateTKEY(r1, r2 *TKEY) bool {
return true
}
func isDuplicateTLSA(r1, r2 *TLSA) bool {
func (r1 *TLSA) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*TLSA)
if !ok {
return false
}
_ = r2
if r1.Usage != r2.Usage {
return false
}
......@@ -865,8 +1211,13 @@ func isDuplicateTLSA(r1, r2 *TLSA) bool {
return true
}
func isDuplicateTSIG(r1, r2 *TSIG) bool {
if !isDulicateName(r1.Algorithm, r2.Algorithm) {
func (r1 *TSIG) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*TSIG)
if !ok {
return false
}
_ = r2
if !isDuplicateName(r1.Algorithm, r2.Algorithm) {
return false
}
if r1.TimeSigned != r2.TimeSigned {
......@@ -896,7 +1247,12 @@ func isDuplicateTSIG(r1, r2 *TSIG) bool {
return true
}
func isDuplicateTXT(r1, r2 *TXT) bool {
func (r1 *TXT) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*TXT)
if !ok {
return false
}
_ = r2
if len(r1.Txt) != len(r2.Txt) {
return false
}
......@@ -908,21 +1264,36 @@ func isDuplicateTXT(r1, r2 *TXT) bool {
return true
}
func isDuplicateUID(r1, r2 *UID) bool {
func (r1 *UID) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*UID)
if !ok {
return false
}
_ = r2
if r1.Uid != r2.Uid {
return false
}
return true
}
func isDuplicateUINFO(r1, r2 *UINFO) bool {
func (r1 *UINFO) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*UINFO)
if !ok {
return false
}
_ = r2
if r1.Uinfo != r2.Uinfo {
return false
}
return true
}
func isDuplicateURI(r1, r2 *URI) bool {
func (r1 *URI) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*URI)
if !ok {
return false
}
_ = r2
if r1.Priority != r2.Priority {
return false
}
......@@ -935,9 +1306,35 @@ func isDuplicateURI(r1, r2 *URI) bool {
return true
}
func isDuplicateX25(r1, r2 *X25) bool {
func (r1 *X25) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*X25)
if !ok {
return false
}
_ = r2
if r1.PSDNAddress != r2.PSDNAddress {
return false
}
return true
}
func (r1 *ZONEMD) isDuplicate(_r2 RR) bool {
r2, ok := _r2.(*ZONEMD)
if !ok {
return false
}
_ = r2
if r1.Serial != r2.Serial {
return false
}
if r1.Scheme != r2.Scheme {
return false
}
if r1.Hash != r2.Hash {
return false
}
if r1.Digest != r2.Digest {
return false
}
return true
}
......@@ -4,82 +4,55 @@ package dns
// pack*() functions
func (rr *A) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *A) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packDataA(rr.A, msg, off)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *AAAA) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *AAAA) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packDataAAAA(rr.AAAA, msg, off)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *AFSDB) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *AFSDB) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint16(rr.Subtype, msg, off)
if err != nil {
return off, err
}
off, err = PackDomainName(rr.Hostname, msg, off, compression, false)
off, err = packDomainName(rr.Hostname, msg, off, compression, false)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *ANY) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
rr.Header().Rdlength = uint16(off - headerEnd)
func (rr *ANY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
return off, nil
}
func (rr *AVC) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
func (rr *APL) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packDataApl(rr.Prefixes, msg, off)
if err != nil {
return off, err
}
headerEnd := off
return off, nil
}
func (rr *AVC) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packStringTxt(rr.Txt, msg, off)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *CAA) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *CAA) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint8(rr.Flag, msg, off)
if err != nil {
return off, err
......@@ -92,16 +65,10 @@ func (rr *CAA) pack(msg []byte, off int, compression map[string]int, compress bo
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *CDNSKEY) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *CDNSKEY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint16(rr.Flags, msg, off)
if err != nil {
return off, err
......@@ -118,16 +85,10 @@ func (rr *CDNSKEY) pack(msg []byte, off int, compression map[string]int, compres
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *CDS) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *CDS) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint16(rr.KeyTag, msg, off)
if err != nil {
return off, err
......@@ -144,16 +105,10 @@ func (rr *CDS) pack(msg []byte, off int, compression map[string]int, compress bo
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *CERT) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *CERT) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint16(rr.Type, msg, off)
if err != nil {
return off, err
......@@ -170,30 +125,18 @@ func (rr *CERT) pack(msg []byte, off int, compression map[string]int, compress b
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *CNAME) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
off, err = PackDomainName(rr.Target, msg, off, compression, compress)
func (rr *CNAME) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packDomainName(rr.Target, msg, off, compression, compress)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *CSYNC) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *CSYNC) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint32(rr.Serial, msg, off)
if err != nil {
return off, err
......@@ -206,30 +149,18 @@ func (rr *CSYNC) pack(msg []byte, off int, compression map[string]int, compress
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *DHCID) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *DHCID) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packStringBase64(rr.Digest, msg, off)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *DLV) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *DLV) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint16(rr.KeyTag, msg, off)
if err != nil {
return off, err
......@@ -246,30 +177,18 @@ func (rr *DLV) pack(msg []byte, off int, compression map[string]int, compress bo
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *DNAME) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
off, err = PackDomainName(rr.Target, msg, off, compression, false)
func (rr *DNAME) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packDomainName(rr.Target, msg, off, compression, false)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *DNSKEY) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *DNSKEY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint16(rr.Flags, msg, off)
if err != nil {
return off, err
......@@ -286,16 +205,10 @@ func (rr *DNSKEY) pack(msg []byte, off int, compression map[string]int, compress
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *DS) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *DS) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint16(rr.KeyTag, msg, off)
if err != nil {
return off, err
......@@ -312,72 +225,42 @@ func (rr *DS) pack(msg []byte, off int, compression map[string]int, compress boo
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *EID) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *EID) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packStringHex(rr.Endpoint, msg, off)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *EUI48) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *EUI48) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint48(rr.Address, msg, off)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *EUI64) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *EUI64) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint64(rr.Address, msg, off)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *GID) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *GID) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint32(rr.Gid, msg, off)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *GPOS) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *GPOS) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packString(rr.Longitude, msg, off)
if err != nil {
return off, err
......@@ -390,16 +273,10 @@ func (rr *GPOS) pack(msg []byte, off int, compression map[string]int, compress b
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *HINFO) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *HINFO) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packString(rr.Cpu, msg, off)
if err != nil {
return off, err
......@@ -408,16 +285,10 @@ func (rr *HINFO) pack(msg []byte, off int, compression map[string]int, compress
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *HIP) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *HIP) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint8(rr.HitLength, msg, off)
if err != nil {
return off, err
......@@ -438,20 +309,30 @@ func (rr *HIP) pack(msg []byte, off int, compression map[string]int, compress bo
if err != nil {
return off, err
}
off, err = packDataDomainNames(rr.RendezvousServers, msg, off, compression, compress)
off, err = packDataDomainNames(rr.RendezvousServers, msg, off, compression, false)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *KEY) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
func (rr *HTTPS) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint16(rr.Priority, msg, off)
if err != nil {
return off, err
}
off, err = packDomainName(rr.Target, msg, off, compression, false)
if err != nil {
return off, err
}
off, err = packDataSVCB(rr.Value, msg, off)
if err != nil {
return off, err
}
headerEnd := off
return off, nil
}
func (rr *KEY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint16(rr.Flags, msg, off)
if err != nil {
return off, err
......@@ -468,34 +349,22 @@ func (rr *KEY) pack(msg []byte, off int, compression map[string]int, compress bo
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *KX) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *KX) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint16(rr.Preference, msg, off)
if err != nil {
return off, err
}
off, err = PackDomainName(rr.Exchanger, msg, off, compression, false)
off, err = packDomainName(rr.Exchanger, msg, off, compression, false)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *L32) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *L32) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint16(rr.Preference, msg, off)
if err != nil {
return off, err
......@@ -504,16 +373,10 @@ func (rr *L32) pack(msg []byte, off int, compression map[string]int, compress bo
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *L64) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *L64) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint16(rr.Preference, msg, off)
if err != nil {
return off, err
......@@ -522,16 +385,10 @@ func (rr *L64) pack(msg []byte, off int, compression map[string]int, compress bo
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *LOC) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *LOC) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint8(rr.Version, msg, off)
if err != nil {
return off, err
......@@ -560,140 +417,86 @@ func (rr *LOC) pack(msg []byte, off int, compression map[string]int, compress bo
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *LP) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *LP) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint16(rr.Preference, msg, off)
if err != nil {
return off, err
}
off, err = PackDomainName(rr.Fqdn, msg, off, compression, false)
off, err = packDomainName(rr.Fqdn, msg, off, compression, false)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *MB) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
off, err = PackDomainName(rr.Mb, msg, off, compression, compress)
func (rr *MB) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packDomainName(rr.Mb, msg, off, compression, compress)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *MD) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
off, err = PackDomainName(rr.Md, msg, off, compression, compress)
func (rr *MD) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packDomainName(rr.Md, msg, off, compression, compress)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *MF) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
func (rr *MF) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packDomainName(rr.Mf, msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
off, err = PackDomainName(rr.Mf, msg, off, compression, compress)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *MG) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
off, err = PackDomainName(rr.Mg, msg, off, compression, compress)
func (rr *MG) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packDomainName(rr.Mg, msg, off, compression, compress)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *MINFO) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
off, err = PackDomainName(rr.Rmail, msg, off, compression, compress)
func (rr *MINFO) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packDomainName(rr.Rmail, msg, off, compression, compress)
if err != nil {
return off, err
}
off, err = PackDomainName(rr.Email, msg, off, compression, compress)
off, err = packDomainName(rr.Email, msg, off, compression, compress)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *MR) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
off, err = PackDomainName(rr.Mr, msg, off, compression, compress)
func (rr *MR) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packDomainName(rr.Mr, msg, off, compression, compress)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *MX) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *MX) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint16(rr.Preference, msg, off)
if err != nil {
return off, err
}
off, err = PackDomainName(rr.Mx, msg, off, compression, compress)
off, err = packDomainName(rr.Mx, msg, off, compression, compress)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *NAPTR) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *NAPTR) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint16(rr.Order, msg, off)
if err != nil {
return off, err
......@@ -714,20 +517,14 @@ func (rr *NAPTR) pack(msg []byte, off int, compression map[string]int, compress
if err != nil {
return off, err
}
off, err = PackDomainName(rr.Replacement, msg, off, compression, false)
off, err = packDomainName(rr.Replacement, msg, off, compression, false)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *NID) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *NID) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint16(rr.Preference, msg, off)
if err != nil {
return off, err
......@@ -736,73 +533,43 @@ func (rr *NID) pack(msg []byte, off int, compression map[string]int, compress bo
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *NIMLOC) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *NIMLOC) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packStringHex(rr.Locator, msg, off)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *NINFO) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *NINFO) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packStringTxt(rr.ZSData, msg, off)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *NS) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
off, err = PackDomainName(rr.Ns, msg, off, compression, compress)
func (rr *NS) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packDomainName(rr.Ns, msg, off, compression, compress)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *NSAPPTR) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
off, err = PackDomainName(rr.Ptr, msg, off, compression, false)
func (rr *NSAPPTR) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packDomainName(rr.Ptr, msg, off, compression, false)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *NSEC) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
off, err = PackDomainName(rr.NextDomain, msg, off, compression, false)
func (rr *NSEC) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packDomainName(rr.NextDomain, msg, off, compression, false)
if err != nil {
return off, err
}
......@@ -810,16 +577,10 @@ func (rr *NSEC) pack(msg []byte, off int, compression map[string]int, compress b
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *NSEC3) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *NSEC3) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint8(rr.Hash, msg, off)
if err != nil {
return off, err
......@@ -855,16 +616,10 @@ func (rr *NSEC3) pack(msg []byte, off int, compression map[string]int, compress
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *NSEC3PARAM) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *NSEC3PARAM) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint8(rr.Hash, msg, off)
if err != nil {
return off, err
......@@ -888,94 +643,66 @@ func (rr *NSEC3PARAM) pack(msg []byte, off int, compression map[string]int, comp
return off, err
}
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *OPENPGPKEY) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
func (rr *NULL) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packStringAny(rr.Data, msg, off)
if err != nil {
return off, err
}
headerEnd := off
return off, nil
}
func (rr *OPENPGPKEY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packStringBase64(rr.PublicKey, msg, off)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *OPT) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *OPT) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packDataOpt(rr.Option, msg, off)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *PTR) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
func (rr *PTR) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packDomainName(rr.Ptr, msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
off, err = PackDomainName(rr.Ptr, msg, off, compression, compress)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *PX) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *PX) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint16(rr.Preference, msg, off)
if err != nil {
return off, err
}
off, err = PackDomainName(rr.Map822, msg, off, compression, false)
off, err = packDomainName(rr.Map822, msg, off, compression, false)
if err != nil {
return off, err
}
off, err = PackDomainName(rr.Mapx400, msg, off, compression, false)
off, err = packDomainName(rr.Mapx400, msg, off, compression, false)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *RFC3597) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *RFC3597) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packStringHex(rr.Rdata, msg, off)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *RKEY) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *RKEY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint16(rr.Flags, msg, off)
if err != nil {
return off, err
......@@ -992,34 +719,22 @@ func (rr *RKEY) pack(msg []byte, off int, compression map[string]int, compress b
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *RP) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
func (rr *RP) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packDomainName(rr.Mbox, msg, off, compression, false)
if err != nil {
return off, err
}
headerEnd := off
off, err = PackDomainName(rr.Mbox, msg, off, compression, false)
off, err = packDomainName(rr.Txt, msg, off, compression, false)
if err != nil {
return off, err
}
off, err = PackDomainName(rr.Txt, msg, off, compression, false)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *RRSIG) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *RRSIG) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint16(rr.TypeCovered, msg, off)
if err != nil {
return off, err
......@@ -1048,7 +763,7 @@ func (rr *RRSIG) pack(msg []byte, off int, compression map[string]int, compress
if err != nil {
return off, err
}
off, err = PackDomainName(rr.SignerName, msg, off, compression, false)
off, err = packDomainName(rr.SignerName, msg, off, compression, false)
if err != nil {
return off, err
}
......@@ -1056,34 +771,22 @@ func (rr *RRSIG) pack(msg []byte, off int, compression map[string]int, compress
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *RT) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *RT) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint16(rr.Preference, msg, off)
if err != nil {
return off, err
}
off, err = PackDomainName(rr.Host, msg, off, compression, compress)
off, err = packDomainName(rr.Host, msg, off, compression, false)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *SIG) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *SIG) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint16(rr.TypeCovered, msg, off)
if err != nil {
return off, err
......@@ -1112,7 +815,7 @@ func (rr *SIG) pack(msg []byte, off int, compression map[string]int, compress bo
if err != nil {
return off, err
}
off, err = PackDomainName(rr.SignerName, msg, off, compression, false)
off, err = packDomainName(rr.SignerName, msg, off, compression, false)
if err != nil {
return off, err
}
......@@ -1120,16 +823,10 @@ func (rr *SIG) pack(msg []byte, off int, compression map[string]int, compress bo
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *SMIMEA) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *SMIMEA) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint8(rr.Usage, msg, off)
if err != nil {
return off, err
......@@ -1146,21 +843,15 @@ func (rr *SMIMEA) pack(msg []byte, off int, compression map[string]int, compress
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *SOA) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
off, err = PackDomainName(rr.Ns, msg, off, compression, compress)
func (rr *SOA) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packDomainName(rr.Ns, msg, off, compression, compress)
if err != nil {
return off, err
}
off, err = PackDomainName(rr.Mbox, msg, off, compression, compress)
off, err = packDomainName(rr.Mbox, msg, off, compression, compress)
if err != nil {
return off, err
}
......@@ -1184,30 +875,18 @@ func (rr *SOA) pack(msg []byte, off int, compression map[string]int, compress bo
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *SPF) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *SPF) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packStringTxt(rr.Txt, msg, off)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *SRV) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *SRV) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint16(rr.Priority, msg, off)
if err != nil {
return off, err
......@@ -1220,20 +899,14 @@ func (rr *SRV) pack(msg []byte, off int, compression map[string]int, compress bo
if err != nil {
return off, err
}
off, err = PackDomainName(rr.Target, msg, off, compression, false)
off, err = packDomainName(rr.Target, msg, off, compression, false)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *SSHFP) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *SSHFP) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint8(rr.Algorithm, msg, off)
if err != nil {
return off, err
......@@ -1246,16 +919,26 @@ func (rr *SSHFP) pack(msg []byte, off int, compression map[string]int, compress
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *TA) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
func (rr *SVCB) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint16(rr.Priority, msg, off)
if err != nil {
return off, err
}
off, err = packDomainName(rr.Target, msg, off, compression, false)
if err != nil {
return off, err
}
off, err = packDataSVCB(rr.Value, msg, off)
if err != nil {
return off, err
}
headerEnd := off
return off, nil
}
func (rr *TA) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint16(rr.KeyTag, msg, off)
if err != nil {
return off, err
......@@ -1272,35 +955,23 @@ func (rr *TA) pack(msg []byte, off int, compression map[string]int, compress boo
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *TALINK) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
off, err = PackDomainName(rr.PreviousName, msg, off, compression, false)
func (rr *TALINK) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packDomainName(rr.PreviousName, msg, off, compression, false)
if err != nil {
return off, err
}
off, err = PackDomainName(rr.NextName, msg, off, compression, false)
off, err = packDomainName(rr.NextName, msg, off, compression, false)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *TKEY) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
off, err = PackDomainName(rr.Algorithm, msg, off, compression, false)
func (rr *TKEY) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packDomainName(rr.Algorithm, msg, off, compression, false)
if err != nil {
return off, err
}
......@@ -1336,16 +1007,10 @@ func (rr *TKEY) pack(msg []byte, off int, compression map[string]int, compress b
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *TLSA) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *TLSA) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint8(rr.Usage, msg, off)
if err != nil {
return off, err
......@@ -1362,17 +1027,11 @@ func (rr *TLSA) pack(msg []byte, off int, compression map[string]int, compress b
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *TSIG) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
off, err = PackDomainName(rr.Algorithm, msg, off, compression, false)
func (rr *TSIG) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packDomainName(rr.Algorithm, msg, off, compression, false)
if err != nil {
return off, err
}
......@@ -1408,58 +1067,34 @@ func (rr *TSIG) pack(msg []byte, off int, compression map[string]int, compress b
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *TXT) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *TXT) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packStringTxt(rr.Txt, msg, off)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *UID) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *UID) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint32(rr.Uid, msg, off)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *UINFO) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *UINFO) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packString(rr.Uinfo, msg, off)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *URI) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil {
return off, err
}
headerEnd := off
func (rr *URI) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint16(rr.Priority, msg, off)
if err != nil {
return off, err
......@@ -1472,2144 +1107,1769 @@ func (rr *URI) pack(msg []byte, off int, compression map[string]int, compress bo
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *X25) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress)
func (rr *X25) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packString(rr.PSDNAddress, msg, off)
if err != nil {
return off, err
}
headerEnd := off
off, err = packString(rr.PSDNAddress, msg, off)
return off, nil
}
func (rr *ZONEMD) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) {
off, err = packUint32(rr.Serial, msg, off)
if err != nil {
return off, err
}
off, err = packUint8(rr.Scheme, msg, off)
if err != nil {
return off, err
}
off, err = packUint8(rr.Hash, msg, off)
if err != nil {
return off, err
}
off, err = packStringHex(rr.Digest, msg, off)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
// unpack*() functions
func unpackA(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(A)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *A) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.A, off, err = unpackDataA(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackAAAA(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(AAAA)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *AAAA) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.AAAA, off, err = unpackDataAAAA(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackAFSDB(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(AFSDB)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *AFSDB) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Subtype, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Hostname, off, err = UnpackDomainName(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackANY(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(ANY)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *ANY) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
return rr, off, err
return off, nil
}
func unpackAVC(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(AVC)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *APL) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Txt, off, err = unpackStringTxt(msg, off)
rr.Prefixes, off, err = unpackDataApl(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackCAA(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(CAA)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *AVC) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Txt, off, err = unpackStringTxt(msg, off)
if err != nil {
return off, err
}
return off, nil
}
func (rr *CAA) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Flag, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Tag, off, err = unpackString(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Value, off, err = unpackStringOctet(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackCDNSKEY(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(CDNSKEY)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *CDNSKEY) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Flags, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Protocol, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Algorithm, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength))
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackCDS(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(CDS)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *CDS) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.KeyTag, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Algorithm, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.DigestType, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Digest, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackCERT(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(CERT)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *CERT) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Type, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.KeyTag, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Algorithm, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Certificate, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength))
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackCNAME(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(CNAME)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *CNAME) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Target, off, err = UnpackDomainName(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackCSYNC(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(CSYNC)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *CSYNC) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Serial, off, err = unpackUint32(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Flags, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.TypeBitMap, off, err = unpackDataNsec(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackDHCID(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(DHCID)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *DHCID) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Digest, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength))
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackDLV(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(DLV)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *DLV) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.KeyTag, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Algorithm, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.DigestType, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Digest, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackDNAME(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(DNAME)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *DNAME) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Target, off, err = UnpackDomainName(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackDNSKEY(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(DNSKEY)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *DNSKEY) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Flags, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Protocol, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Algorithm, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength))
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackDS(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(DS)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *DS) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.KeyTag, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Algorithm, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.DigestType, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Digest, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackEID(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(EID)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *EID) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Endpoint, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackEUI48(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(EUI48)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *EUI48) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Address, off, err = unpackUint48(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackEUI64(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(EUI64)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *EUI64) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Address, off, err = unpackUint64(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackGID(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(GID)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *GID) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Gid, off, err = unpackUint32(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackGPOS(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(GPOS)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *GPOS) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Longitude, off, err = unpackString(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Latitude, off, err = unpackString(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Altitude, off, err = unpackString(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackHINFO(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(HINFO)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *HINFO) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Cpu, off, err = unpackString(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Os, off, err = unpackString(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackHIP(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(HIP)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *HIP) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.HitLength, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.PublicKeyAlgorithm, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.PublicKeyLength, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Hit, off, err = unpackStringHex(msg, off, off+int(rr.HitLength))
if err != nil {
return rr, off, err
return off, err
}
rr.PublicKey, off, err = unpackStringBase64(msg, off, off+int(rr.PublicKeyLength))
if err != nil {
return rr, off, err
return off, err
}
rr.RendezvousServers, off, err = unpackDataDomainNames(msg, off, rdStart+int(rr.Hdr.Rdlength))
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackKEY(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(KEY)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
func (rr *HTTPS) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Priority, off, err = unpackUint16(msg, off)
if err != nil {
return off, err
}
if off == len(msg) {
return off, nil
}
rr.Target, off, err = UnpackDomainName(msg, off)
if err != nil {
return off, err
}
if off == len(msg) {
return off, nil
}
rr.Value, off, err = unpackDataSVCB(msg, off)
if err != nil {
return off, err
}
var err error
return off, nil
}
func (rr *KEY) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Flags, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Protocol, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Algorithm, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength))
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackKX(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(KX)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *KX) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Preference, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Exchanger, off, err = UnpackDomainName(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackL32(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(L32)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *L32) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Preference, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Locator32, off, err = unpackDataA(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackL64(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(L64)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *L64) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Preference, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Locator64, off, err = unpackUint64(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackLOC(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(LOC)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *LOC) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Version, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Size, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.HorizPre, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.VertPre, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Latitude, off, err = unpackUint32(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Longitude, off, err = unpackUint32(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Altitude, off, err = unpackUint32(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackLP(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(LP)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *LP) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Preference, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Fqdn, off, err = UnpackDomainName(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackMB(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(MB)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *MB) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Mb, off, err = UnpackDomainName(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackMD(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(MD)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *MD) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Md, off, err = UnpackDomainName(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackMF(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(MF)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *MF) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Mf, off, err = UnpackDomainName(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackMG(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(MG)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *MG) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Mg, off, err = UnpackDomainName(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackMINFO(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(MINFO)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *MINFO) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Rmail, off, err = UnpackDomainName(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Email, off, err = UnpackDomainName(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackMR(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(MR)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *MR) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Mr, off, err = UnpackDomainName(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackMX(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(MX)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *MX) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Preference, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Mx, off, err = UnpackDomainName(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackNAPTR(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(NAPTR)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *NAPTR) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Order, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Preference, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Flags, off, err = unpackString(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Service, off, err = unpackString(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Regexp, off, err = unpackString(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Replacement, off, err = UnpackDomainName(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackNID(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(NID)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *NID) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Preference, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.NodeID, off, err = unpackUint64(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackNIMLOC(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(NIMLOC)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *NIMLOC) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Locator, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackNINFO(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(NINFO)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *NINFO) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.ZSData, off, err = unpackStringTxt(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackNS(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(NS)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *NS) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Ns, off, err = UnpackDomainName(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackNSAPPTR(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(NSAPPTR)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *NSAPPTR) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Ptr, off, err = UnpackDomainName(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackNSEC(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(NSEC)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *NSEC) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.NextDomain, off, err = UnpackDomainName(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.TypeBitMap, off, err = unpackDataNsec(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackNSEC3(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(NSEC3)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *NSEC3) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Hash, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Flags, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Iterations, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.SaltLength, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Salt, off, err = unpackStringHex(msg, off, off+int(rr.SaltLength))
if err != nil {
return rr, off, err
return off, err
}
rr.HashLength, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.NextDomain, off, err = unpackStringBase32(msg, off, off+int(rr.HashLength))
if err != nil {
return rr, off, err
return off, err
}
rr.TypeBitMap, off, err = unpackDataNsec(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackNSEC3PARAM(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(NSEC3PARAM)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *NSEC3PARAM) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Hash, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Flags, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Iterations, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.SaltLength, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Salt, off, err = unpackStringHex(msg, off, off+int(rr.SaltLength))
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackOPENPGPKEY(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(OPENPGPKEY)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
func (rr *NULL) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Data, off, err = unpackStringAny(msg, off, rdStart+int(rr.Hdr.Rdlength))
if err != nil {
return off, err
}
var err error
return off, nil
}
func (rr *OPENPGPKEY) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength))
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackOPT(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(OPT)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *OPT) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Option, off, err = unpackDataOpt(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackPTR(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(PTR)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *PTR) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Ptr, off, err = UnpackDomainName(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackPX(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(PX)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *PX) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Preference, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Map822, off, err = UnpackDomainName(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Mapx400, off, err = UnpackDomainName(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackRFC3597(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(RFC3597)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *RFC3597) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Rdata, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackRKEY(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(RKEY)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *RKEY) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Flags, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Protocol, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Algorithm, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength))
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackRP(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(RP)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *RP) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Mbox, off, err = UnpackDomainName(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Txt, off, err = UnpackDomainName(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackRRSIG(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(RRSIG)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *RRSIG) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.TypeCovered, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Algorithm, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Labels, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.OrigTtl, off, err = unpackUint32(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Expiration, off, err = unpackUint32(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Inception, off, err = unpackUint32(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.KeyTag, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.SignerName, off, err = UnpackDomainName(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Signature, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength))
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackRT(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(RT)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *RT) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Preference, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Host, off, err = UnpackDomainName(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackSIG(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(SIG)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *SIG) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.TypeCovered, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Algorithm, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Labels, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.OrigTtl, off, err = unpackUint32(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Expiration, off, err = unpackUint32(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Inception, off, err = unpackUint32(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.KeyTag, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.SignerName, off, err = UnpackDomainName(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Signature, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength))
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackSMIMEA(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(SMIMEA)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *SMIMEA) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Usage, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Selector, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.MatchingType, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Certificate, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackSOA(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(SOA)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *SOA) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Ns, off, err = UnpackDomainName(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Mbox, off, err = UnpackDomainName(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Serial, off, err = unpackUint32(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Refresh, off, err = unpackUint32(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Retry, off, err = unpackUint32(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Expire, off, err = unpackUint32(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Minttl, off, err = unpackUint32(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackSPF(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(SPF)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *SPF) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Txt, off, err = unpackStringTxt(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackSRV(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(SRV)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *SRV) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Priority, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Weight, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Port, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Target, off, err = UnpackDomainName(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackSSHFP(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(SSHFP)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *SSHFP) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Algorithm, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Type, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.FingerPrint, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackTA(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(TA)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
func (rr *SVCB) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Priority, off, err = unpackUint16(msg, off)
if err != nil {
return off, err
}
if off == len(msg) {
return off, nil
}
rr.Target, off, err = UnpackDomainName(msg, off)
if err != nil {
return off, err
}
if off == len(msg) {
return off, nil
}
var err error
rr.Value, off, err = unpackDataSVCB(msg, off)
if err != nil {
return off, err
}
return off, nil
}
func (rr *TA) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.KeyTag, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Algorithm, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.DigestType, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Digest, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackTALINK(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(TALINK)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *TALINK) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.PreviousName, off, err = UnpackDomainName(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.NextName, off, err = UnpackDomainName(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackTKEY(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(TKEY)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *TKEY) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Algorithm, off, err = UnpackDomainName(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Inception, off, err = unpackUint32(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Expiration, off, err = unpackUint32(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Mode, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Error, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.KeySize, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Key, off, err = unpackStringHex(msg, off, off+int(rr.KeySize))
if err != nil {
return rr, off, err
return off, err
}
rr.OtherLen, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.OtherData, off, err = unpackStringHex(msg, off, off+int(rr.OtherLen))
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackTLSA(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(TLSA)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *TLSA) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Usage, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Selector, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.MatchingType, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Certificate, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackTSIG(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(TSIG)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *TSIG) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Algorithm, off, err = UnpackDomainName(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.TimeSigned, off, err = unpackUint48(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Fudge, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.MACSize, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.MAC, off, err = unpackStringHex(msg, off, off+int(rr.MACSize))
if err != nil {
return rr, off, err
return off, err
}
rr.OrigId, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Error, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.OtherLen, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.OtherData, off, err = unpackStringHex(msg, off, off+int(rr.OtherLen))
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackTXT(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(TXT)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *TXT) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Txt, off, err = unpackStringTxt(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackUID(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(UID)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *UID) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Uid, off, err = unpackUint32(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackUINFO(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(UINFO)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *UINFO) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Uinfo, off, err = unpackString(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackURI(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(URI)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *URI) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Priority, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Weight, off, err = unpackUint16(msg, off)
if err != nil {
return rr, off, err
return off, err
}
if off == len(msg) {
return rr, off, nil
return off, nil
}
rr.Target, off, err = unpackStringOctet(msg, off)
if err != nil {
return rr, off, err
return off, err
}
return rr, off, err
return off, nil
}
func unpackX25(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(X25)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
func (rr *X25) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.PSDNAddress, off, err = unpackString(msg, off)
if err != nil {
return rr, off, err
}
return rr, off, err
}
var typeToUnpack = map[uint16]func(RR_Header, []byte, int) (RR, int, error){
TypeA: unpackA,
TypeAAAA: unpackAAAA,
TypeAFSDB: unpackAFSDB,
TypeANY: unpackANY,
TypeAVC: unpackAVC,
TypeCAA: unpackCAA,
TypeCDNSKEY: unpackCDNSKEY,
TypeCDS: unpackCDS,
TypeCERT: unpackCERT,
TypeCNAME: unpackCNAME,
TypeCSYNC: unpackCSYNC,
TypeDHCID: unpackDHCID,
TypeDLV: unpackDLV,
TypeDNAME: unpackDNAME,
TypeDNSKEY: unpackDNSKEY,
TypeDS: unpackDS,
TypeEID: unpackEID,
TypeEUI48: unpackEUI48,
TypeEUI64: unpackEUI64,
TypeGID: unpackGID,
TypeGPOS: unpackGPOS,
TypeHINFO: unpackHINFO,
TypeHIP: unpackHIP,
TypeKEY: unpackKEY,
TypeKX: unpackKX,
TypeL32: unpackL32,
TypeL64: unpackL64,
TypeLOC: unpackLOC,
TypeLP: unpackLP,
TypeMB: unpackMB,
TypeMD: unpackMD,
TypeMF: unpackMF,
TypeMG: unpackMG,
TypeMINFO: unpackMINFO,
TypeMR: unpackMR,
TypeMX: unpackMX,
TypeNAPTR: unpackNAPTR,
TypeNID: unpackNID,
TypeNIMLOC: unpackNIMLOC,
TypeNINFO: unpackNINFO,
TypeNS: unpackNS,
TypeNSAPPTR: unpackNSAPPTR,
TypeNSEC: unpackNSEC,
TypeNSEC3: unpackNSEC3,
TypeNSEC3PARAM: unpackNSEC3PARAM,
TypeOPENPGPKEY: unpackOPENPGPKEY,
TypeOPT: unpackOPT,
TypePTR: unpackPTR,
TypePX: unpackPX,
TypeRKEY: unpackRKEY,
TypeRP: unpackRP,
TypeRRSIG: unpackRRSIG,
TypeRT: unpackRT,
TypeSIG: unpackSIG,
TypeSMIMEA: unpackSMIMEA,
TypeSOA: unpackSOA,
TypeSPF: unpackSPF,
TypeSRV: unpackSRV,
TypeSSHFP: unpackSSHFP,
TypeTA: unpackTA,
TypeTALINK: unpackTALINK,
TypeTKEY: unpackTKEY,
TypeTLSA: unpackTLSA,
TypeTSIG: unpackTSIG,
TypeTXT: unpackTXT,
TypeUID: unpackUID,
TypeUINFO: unpackUINFO,
TypeURI: unpackURI,
TypeX25: unpackX25,
return off, err
}
return off, nil
}
func (rr *ZONEMD) unpack(msg []byte, off int) (off1 int, err error) {
rdStart := off
_ = rdStart
rr.Serial, off, err = unpackUint32(msg, off)
if err != nil {
return off, err
}
if off == len(msg) {
return off, nil
}
rr.Scheme, off, err = unpackUint8(msg, off)
if err != nil {
return off, err
}
if off == len(msg) {
return off, nil
}
rr.Hash, off, err = unpackUint8(msg, off)
if err != nil {
return off, err
}
if off == len(msg) {
return off, nil
}
rr.Digest, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
if err != nil {
return off, err
}
return off, nil
}
......@@ -13,6 +13,7 @@ var TypeToRR = map[uint16]func() RR{
TypeAAAA: func() RR { return new(AAAA) },
TypeAFSDB: func() RR { return new(AFSDB) },
TypeANY: func() RR { return new(ANY) },
TypeAPL: func() RR { return new(APL) },
TypeAVC: func() RR { return new(AVC) },
TypeCAA: func() RR { return new(CAA) },
TypeCDNSKEY: func() RR { return new(CDNSKEY) },
......@@ -32,6 +33,7 @@ var TypeToRR = map[uint16]func() RR{
TypeGPOS: func() RR { return new(GPOS) },
TypeHINFO: func() RR { return new(HINFO) },
TypeHIP: func() RR { return new(HIP) },
TypeHTTPS: func() RR { return new(HTTPS) },
TypeKEY: func() RR { return new(KEY) },
TypeKX: func() RR { return new(KX) },
TypeL32: func() RR { return new(L32) },
......@@ -54,6 +56,7 @@ var TypeToRR = map[uint16]func() RR{
TypeNSEC: func() RR { return new(NSEC) },
TypeNSEC3: func() RR { return new(NSEC3) },
TypeNSEC3PARAM: func() RR { return new(NSEC3PARAM) },
TypeNULL: func() RR { return new(NULL) },
TypeOPENPGPKEY: func() RR { return new(OPENPGPKEY) },
TypeOPT: func() RR { return new(OPT) },
TypePTR: func() RR { return new(PTR) },
......@@ -68,6 +71,7 @@ var TypeToRR = map[uint16]func() RR{
TypeSPF: func() RR { return new(SPF) },
TypeSRV: func() RR { return new(SRV) },
TypeSSHFP: func() RR { return new(SSHFP) },
TypeSVCB: func() RR { return new(SVCB) },
TypeTA: func() RR { return new(TA) },
TypeTALINK: func() RR { return new(TALINK) },
TypeTKEY: func() RR { return new(TKEY) },
......@@ -78,6 +82,7 @@ var TypeToRR = map[uint16]func() RR{
TypeUINFO: func() RR { return new(UINFO) },
TypeURI: func() RR { return new(URI) },
TypeX25: func() RR { return new(X25) },
TypeZONEMD: func() RR { return new(ZONEMD) },
}
// TypeToString is a map of strings for each RR type.
......@@ -86,6 +91,7 @@ var TypeToString = map[uint16]string{
TypeAAAA: "AAAA",
TypeAFSDB: "AFSDB",
TypeANY: "ANY",
TypeAPL: "APL",
TypeATMA: "ATMA",
TypeAVC: "AVC",
TypeAXFR: "AXFR",
......@@ -107,6 +113,7 @@ var TypeToString = map[uint16]string{
TypeGPOS: "GPOS",
TypeHINFO: "HINFO",
TypeHIP: "HIP",
TypeHTTPS: "HTTPS",
TypeISDN: "ISDN",
TypeIXFR: "IXFR",
TypeKEY: "KEY",
......@@ -150,6 +157,7 @@ var TypeToString = map[uint16]string{
TypeSPF: "SPF",
TypeSRV: "SRV",
TypeSSHFP: "SSHFP",
TypeSVCB: "SVCB",
TypeTA: "TA",
TypeTALINK: "TALINK",
TypeTKEY: "TKEY",
......@@ -161,6 +169,7 @@ var TypeToString = map[uint16]string{
TypeUNSPEC: "UNSPEC",
TypeURI: "URI",
TypeX25: "X25",
TypeZONEMD: "ZONEMD",
TypeNSAPPTR: "NSAP-PTR",
}
......@@ -168,6 +177,7 @@ func (rr *A) Header() *RR_Header { return &rr.Hdr }
func (rr *AAAA) Header() *RR_Header { return &rr.Hdr }
func (rr *AFSDB) Header() *RR_Header { return &rr.Hdr }
func (rr *ANY) Header() *RR_Header { return &rr.Hdr }
func (rr *APL) Header() *RR_Header { return &rr.Hdr }
func (rr *AVC) Header() *RR_Header { return &rr.Hdr }
func (rr *CAA) Header() *RR_Header { return &rr.Hdr }
func (rr *CDNSKEY) Header() *RR_Header { return &rr.Hdr }
......@@ -187,6 +197,7 @@ func (rr *GID) Header() *RR_Header { return &rr.Hdr }
func (rr *GPOS) Header() *RR_Header { return &rr.Hdr }
func (rr *HINFO) Header() *RR_Header { return &rr.Hdr }
func (rr *HIP) Header() *RR_Header { return &rr.Hdr }
func (rr *HTTPS) Header() *RR_Header { return &rr.Hdr }
func (rr *KEY) Header() *RR_Header { return &rr.Hdr }
func (rr *KX) Header() *RR_Header { return &rr.Hdr }
func (rr *L32) Header() *RR_Header { return &rr.Hdr }
......@@ -209,6 +220,7 @@ func (rr *NSAPPTR) Header() *RR_Header { return &rr.Hdr }
func (rr *NSEC) Header() *RR_Header { return &rr.Hdr }
func (rr *NSEC3) Header() *RR_Header { return &rr.Hdr }
func (rr *NSEC3PARAM) Header() *RR_Header { return &rr.Hdr }
func (rr *NULL) Header() *RR_Header { return &rr.Hdr }
func (rr *OPENPGPKEY) Header() *RR_Header { return &rr.Hdr }
func (rr *OPT) Header() *RR_Header { return &rr.Hdr }
func (rr *PTR) Header() *RR_Header { return &rr.Hdr }
......@@ -224,6 +236,7 @@ func (rr *SOA) Header() *RR_Header { return &rr.Hdr }
func (rr *SPF) Header() *RR_Header { return &rr.Hdr }
func (rr *SRV) Header() *RR_Header { return &rr.Hdr }
func (rr *SSHFP) Header() *RR_Header { return &rr.Hdr }
func (rr *SVCB) Header() *RR_Header { return &rr.Hdr }
func (rr *TA) Header() *RR_Header { return &rr.Hdr }
func (rr *TALINK) Header() *RR_Header { return &rr.Hdr }
func (rr *TKEY) Header() *RR_Header { return &rr.Hdr }
......@@ -234,146 +247,160 @@ func (rr *UID) Header() *RR_Header { return &rr.Hdr }
func (rr *UINFO) Header() *RR_Header { return &rr.Hdr }
func (rr *URI) Header() *RR_Header { return &rr.Hdr }
func (rr *X25) Header() *RR_Header { return &rr.Hdr }
func (rr *ZONEMD) Header() *RR_Header { return &rr.Hdr }
// len() functions
func (rr *A) len() int {
l := rr.Hdr.len()
l += net.IPv4len // A
func (rr *A) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
if len(rr.A) != 0 {
l += net.IPv4len
}
return l
}
func (rr *AAAA) len() int {
l := rr.Hdr.len()
l += net.IPv6len // AAAA
func (rr *AAAA) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
if len(rr.AAAA) != 0 {
l += net.IPv6len
}
return l
}
func (rr *AFSDB) len() int {
l := rr.Hdr.len()
func (rr *AFSDB) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += 2 // Subtype
l += len(rr.Hostname) + 1
l += domainNameLen(rr.Hostname, off+l, compression, false)
return l
}
func (rr *ANY) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
return l
}
func (rr *ANY) len() int {
l := rr.Hdr.len()
func (rr *APL) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
for _, x := range rr.Prefixes {
l += x.len()
}
return l
}
func (rr *AVC) len() int {
l := rr.Hdr.len()
func (rr *AVC) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
for _, x := range rr.Txt {
l += len(x) + 1
}
return l
}
func (rr *CAA) len() int {
l := rr.Hdr.len()
func (rr *CAA) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l++ // Flag
l += len(rr.Tag) + 1
l += len(rr.Value)
return l
}
func (rr *CERT) len() int {
l := rr.Hdr.len()
func (rr *CERT) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += 2 // Type
l += 2 // KeyTag
l++ // Algorithm
l += base64.StdEncoding.DecodedLen(len(rr.Certificate))
return l
}
func (rr *CNAME) len() int {
l := rr.Hdr.len()
l += len(rr.Target) + 1
func (rr *CNAME) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += domainNameLen(rr.Target, off+l, compression, true)
return l
}
func (rr *DHCID) len() int {
l := rr.Hdr.len()
func (rr *DHCID) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += base64.StdEncoding.DecodedLen(len(rr.Digest))
return l
}
func (rr *DNAME) len() int {
l := rr.Hdr.len()
l += len(rr.Target) + 1
func (rr *DNAME) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += domainNameLen(rr.Target, off+l, compression, false)
return l
}
func (rr *DNSKEY) len() int {
l := rr.Hdr.len()
func (rr *DNSKEY) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += 2 // Flags
l++ // Protocol
l++ // Algorithm
l += base64.StdEncoding.DecodedLen(len(rr.PublicKey))
return l
}
func (rr *DS) len() int {
l := rr.Hdr.len()
func (rr *DS) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += 2 // KeyTag
l++ // Algorithm
l++ // DigestType
l += len(rr.Digest)/2 + 1
l += len(rr.Digest) / 2
return l
}
func (rr *EID) len() int {
l := rr.Hdr.len()
l += len(rr.Endpoint)/2 + 1
func (rr *EID) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += len(rr.Endpoint) / 2
return l
}
func (rr *EUI48) len() int {
l := rr.Hdr.len()
func (rr *EUI48) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += 6 // Address
return l
}
func (rr *EUI64) len() int {
l := rr.Hdr.len()
func (rr *EUI64) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += 8 // Address
return l
}
func (rr *GID) len() int {
l := rr.Hdr.len()
func (rr *GID) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += 4 // Gid
return l
}
func (rr *GPOS) len() int {
l := rr.Hdr.len()
func (rr *GPOS) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += len(rr.Longitude) + 1
l += len(rr.Latitude) + 1
l += len(rr.Altitude) + 1
return l
}
func (rr *HINFO) len() int {
l := rr.Hdr.len()
func (rr *HINFO) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += len(rr.Cpu) + 1
l += len(rr.Os) + 1
return l
}
func (rr *HIP) len() int {
l := rr.Hdr.len()
func (rr *HIP) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l++ // HitLength
l++ // PublicKeyAlgorithm
l += 2 // PublicKeyLength
l += len(rr.Hit) / 2
l += base64.StdEncoding.DecodedLen(len(rr.PublicKey))
for _, x := range rr.RendezvousServers {
l += len(x) + 1
l += domainNameLen(x, off+l, compression, false)
}
return l
}
func (rr *KX) len() int {
l := rr.Hdr.len()
func (rr *KX) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += 2 // Preference
l += len(rr.Exchanger) + 1
l += domainNameLen(rr.Exchanger, off+l, compression, false)
return l
}
func (rr *L32) len() int {
l := rr.Hdr.len()
func (rr *L32) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += 2 // Preference
l += net.IPv4len // Locator32
if len(rr.Locator32) != 0 {
l += net.IPv4len
}
return l
}
func (rr *L64) len() int {
l := rr.Hdr.len()
func (rr *L64) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += 2 // Preference
l += 8 // Locator64
return l
}
func (rr *LOC) len() int {
l := rr.Hdr.len()
func (rr *LOC) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l++ // Version
l++ // Size
l++ // HorizPre
......@@ -383,89 +410,89 @@ func (rr *LOC) len() int {
l += 4 // Altitude
return l
}
func (rr *LP) len() int {
l := rr.Hdr.len()
func (rr *LP) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += 2 // Preference
l += len(rr.Fqdn) + 1
l += domainNameLen(rr.Fqdn, off+l, compression, false)
return l
}
func (rr *MB) len() int {
l := rr.Hdr.len()
l += len(rr.Mb) + 1
func (rr *MB) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += domainNameLen(rr.Mb, off+l, compression, true)
return l
}
func (rr *MD) len() int {
l := rr.Hdr.len()
l += len(rr.Md) + 1
func (rr *MD) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += domainNameLen(rr.Md, off+l, compression, true)
return l
}
func (rr *MF) len() int {
l := rr.Hdr.len()
l += len(rr.Mf) + 1
func (rr *MF) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += domainNameLen(rr.Mf, off+l, compression, true)
return l
}
func (rr *MG) len() int {
l := rr.Hdr.len()
l += len(rr.Mg) + 1
func (rr *MG) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += domainNameLen(rr.Mg, off+l, compression, true)
return l
}
func (rr *MINFO) len() int {
l := rr.Hdr.len()
l += len(rr.Rmail) + 1
l += len(rr.Email) + 1
func (rr *MINFO) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += domainNameLen(rr.Rmail, off+l, compression, true)
l += domainNameLen(rr.Email, off+l, compression, true)
return l
}
func (rr *MR) len() int {
l := rr.Hdr.len()
l += len(rr.Mr) + 1
func (rr *MR) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += domainNameLen(rr.Mr, off+l, compression, true)
return l
}
func (rr *MX) len() int {
l := rr.Hdr.len()
func (rr *MX) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += 2 // Preference
l += len(rr.Mx) + 1
l += domainNameLen(rr.Mx, off+l, compression, true)
return l
}
func (rr *NAPTR) len() int {
l := rr.Hdr.len()
func (rr *NAPTR) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += 2 // Order
l += 2 // Preference
l += len(rr.Flags) + 1
l += len(rr.Service) + 1
l += len(rr.Regexp) + 1
l += len(rr.Replacement) + 1
l += domainNameLen(rr.Replacement, off+l, compression, false)
return l
}
func (rr *NID) len() int {
l := rr.Hdr.len()
func (rr *NID) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += 2 // Preference
l += 8 // NodeID
return l
}
func (rr *NIMLOC) len() int {
l := rr.Hdr.len()
l += len(rr.Locator)/2 + 1
func (rr *NIMLOC) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += len(rr.Locator) / 2
return l
}
func (rr *NINFO) len() int {
l := rr.Hdr.len()
func (rr *NINFO) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
for _, x := range rr.ZSData {
l += len(x) + 1
}
return l
}
func (rr *NS) len() int {
l := rr.Hdr.len()
l += len(rr.Ns) + 1
func (rr *NS) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += domainNameLen(rr.Ns, off+l, compression, true)
return l
}
func (rr *NSAPPTR) len() int {
l := rr.Hdr.len()
l += len(rr.Ptr) + 1
func (rr *NSAPPTR) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += domainNameLen(rr.Ptr, off+l, compression, false)
return l
}
func (rr *NSEC3PARAM) len() int {
l := rr.Hdr.len()
func (rr *NSEC3PARAM) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l++ // Hash
l++ // Flags
l += 2 // Iterations
......@@ -473,44 +500,49 @@ func (rr *NSEC3PARAM) len() int {
l += len(rr.Salt) / 2
return l
}
func (rr *OPENPGPKEY) len() int {
l := rr.Hdr.len()
func (rr *NULL) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += len(rr.Data)
return l
}
func (rr *OPENPGPKEY) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += base64.StdEncoding.DecodedLen(len(rr.PublicKey))
return l
}
func (rr *PTR) len() int {
l := rr.Hdr.len()
l += len(rr.Ptr) + 1
func (rr *PTR) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += domainNameLen(rr.Ptr, off+l, compression, true)
return l
}
func (rr *PX) len() int {
l := rr.Hdr.len()
func (rr *PX) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += 2 // Preference
l += len(rr.Map822) + 1
l += len(rr.Mapx400) + 1
l += domainNameLen(rr.Map822, off+l, compression, false)
l += domainNameLen(rr.Mapx400, off+l, compression, false)
return l
}
func (rr *RFC3597) len() int {
l := rr.Hdr.len()
l += len(rr.Rdata)/2 + 1
func (rr *RFC3597) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += len(rr.Rdata) / 2
return l
}
func (rr *RKEY) len() int {
l := rr.Hdr.len()
func (rr *RKEY) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += 2 // Flags
l++ // Protocol
l++ // Algorithm
l += base64.StdEncoding.DecodedLen(len(rr.PublicKey))
return l
}
func (rr *RP) len() int {
l := rr.Hdr.len()
l += len(rr.Mbox) + 1
l += len(rr.Txt) + 1
func (rr *RP) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += domainNameLen(rr.Mbox, off+l, compression, false)
l += domainNameLen(rr.Txt, off+l, compression, false)
return l
}
func (rr *RRSIG) len() int {
l := rr.Hdr.len()
func (rr *RRSIG) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += 2 // TypeCovered
l++ // Algorithm
l++ // Labels
......@@ -518,28 +550,28 @@ func (rr *RRSIG) len() int {
l += 4 // Expiration
l += 4 // Inception
l += 2 // KeyTag
l += len(rr.SignerName) + 1
l += domainNameLen(rr.SignerName, off+l, compression, false)
l += base64.StdEncoding.DecodedLen(len(rr.Signature))
return l
}
func (rr *RT) len() int {
l := rr.Hdr.len()
func (rr *RT) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += 2 // Preference
l += len(rr.Host) + 1
l += domainNameLen(rr.Host, off+l, compression, false)
return l
}
func (rr *SMIMEA) len() int {
l := rr.Hdr.len()
func (rr *SMIMEA) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l++ // Usage
l++ // Selector
l++ // MatchingType
l += len(rr.Certificate)/2 + 1
l += len(rr.Certificate) / 2
return l
}
func (rr *SOA) len() int {
l := rr.Hdr.len()
l += len(rr.Ns) + 1
l += len(rr.Mbox) + 1
func (rr *SOA) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += domainNameLen(rr.Ns, off+l, compression, true)
l += domainNameLen(rr.Mbox, off+l, compression, true)
l += 4 // Serial
l += 4 // Refresh
l += 4 // Retry
......@@ -547,45 +579,54 @@ func (rr *SOA) len() int {
l += 4 // Minttl
return l
}
func (rr *SPF) len() int {
l := rr.Hdr.len()
func (rr *SPF) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
for _, x := range rr.Txt {
l += len(x) + 1
}
return l
}
func (rr *SRV) len() int {
l := rr.Hdr.len()
func (rr *SRV) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += 2 // Priority
l += 2 // Weight
l += 2 // Port
l += len(rr.Target) + 1
l += domainNameLen(rr.Target, off+l, compression, false)
return l
}
func (rr *SSHFP) len() int {
l := rr.Hdr.len()
func (rr *SSHFP) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l++ // Algorithm
l++ // Type
l += len(rr.FingerPrint)/2 + 1
l += len(rr.FingerPrint) / 2
return l
}
func (rr *TA) len() int {
l := rr.Hdr.len()
func (rr *SVCB) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += 2 // Priority
l += domainNameLen(rr.Target, off+l, compression, false)
for _, x := range rr.Value {
l += 4 + int(x.len())
}
return l
}
func (rr *TA) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += 2 // KeyTag
l++ // Algorithm
l++ // DigestType
l += len(rr.Digest)/2 + 1
l += len(rr.Digest) / 2
return l
}
func (rr *TALINK) len() int {
l := rr.Hdr.len()
l += len(rr.PreviousName) + 1
l += len(rr.NextName) + 1
func (rr *TALINK) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += domainNameLen(rr.PreviousName, off+l, compression, false)
l += domainNameLen(rr.NextName, off+l, compression, false)
return l
}
func (rr *TKEY) len() int {
l := rr.Hdr.len()
l += len(rr.Algorithm) + 1
func (rr *TKEY) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += domainNameLen(rr.Algorithm, off+l, compression, false)
l += 4 // Inception
l += 4 // Expiration
l += 2 // Mode
......@@ -596,17 +637,17 @@ func (rr *TKEY) len() int {
l += len(rr.OtherData) / 2
return l
}
func (rr *TLSA) len() int {
l := rr.Hdr.len()
func (rr *TLSA) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l++ // Usage
l++ // Selector
l++ // MatchingType
l += len(rr.Certificate)/2 + 1
l += len(rr.Certificate) / 2
return l
}
func (rr *TSIG) len() int {
l := rr.Hdr.len()
l += len(rr.Algorithm) + 1
func (rr *TSIG) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += domainNameLen(rr.Algorithm, off+l, compression, false)
l += 6 // TimeSigned
l += 2 // Fudge
l += 2 // MACSize
......@@ -617,35 +658,43 @@ func (rr *TSIG) len() int {
l += len(rr.OtherData) / 2
return l
}
func (rr *TXT) len() int {
l := rr.Hdr.len()
func (rr *TXT) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
for _, x := range rr.Txt {
l += len(x) + 1
}
return l
}
func (rr *UID) len() int {
l := rr.Hdr.len()
func (rr *UID) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += 4 // Uid
return l
}
func (rr *UINFO) len() int {
l := rr.Hdr.len()
func (rr *UINFO) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += len(rr.Uinfo) + 1
return l
}
func (rr *URI) len() int {
l := rr.Hdr.len()
func (rr *URI) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += 2 // Priority
l += 2 // Weight
l += len(rr.Target)
return l
}
func (rr *X25) len() int {
l := rr.Hdr.len()
func (rr *X25) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += len(rr.PSDNAddress) + 1
return l
}
func (rr *ZONEMD) len(off int, compression map[string]struct{}) int {
l := rr.Hdr.len(off, compression)
l += 4 // Serial
l++ // Scheme
l++ // Hash
l += len(rr.Digest) / 2
return l
}
// copy() functions
func (rr *A) copy() RR {
......@@ -660,6 +709,13 @@ func (rr *AFSDB) copy() RR {
func (rr *ANY) copy() RR {
return &ANY{rr.Hdr}
}
func (rr *APL) copy() RR {
Prefixes := make([]APLPrefix, len(rr.Prefixes))
for i, e := range rr.Prefixes {
Prefixes[i] = e.copy()
}
return &APL{rr.Hdr, Prefixes}
}
func (rr *AVC) copy() RR {
Txt := make([]string, len(rr.Txt))
copy(Txt, rr.Txt)
......@@ -668,6 +724,12 @@ func (rr *AVC) copy() RR {
func (rr *CAA) copy() RR {
return &CAA{rr.Hdr, rr.Flag, rr.Tag, rr.Value}
}
func (rr *CDNSKEY) copy() RR {
return &CDNSKEY{*rr.DNSKEY.copy().(*DNSKEY)}
}
func (rr *CDS) copy() RR {
return &CDS{*rr.DS.copy().(*DS)}
}
func (rr *CERT) copy() RR {
return &CERT{rr.Hdr, rr.Type, rr.KeyTag, rr.Algorithm, rr.Certificate}
}
......@@ -682,6 +744,9 @@ func (rr *CSYNC) copy() RR {
func (rr *DHCID) copy() RR {
return &DHCID{rr.Hdr, rr.Digest}
}
func (rr *DLV) copy() RR {
return &DLV{*rr.DS.copy().(*DS)}
}
func (rr *DNAME) copy() RR {
return &DNAME{rr.Hdr, rr.Target}
}
......@@ -714,6 +779,12 @@ func (rr *HIP) copy() RR {
copy(RendezvousServers, rr.RendezvousServers)
return &HIP{rr.Hdr, rr.HitLength, rr.PublicKeyAlgorithm, rr.PublicKeyLength, rr.Hit, rr.PublicKey, RendezvousServers}
}
func (rr *HTTPS) copy() RR {
return &HTTPS{*rr.SVCB.copy().(*SVCB)}
}
func (rr *KEY) copy() RR {
return &KEY{*rr.DNSKEY.copy().(*DNSKEY)}
}
func (rr *KX) copy() RR {
return &KX{rr.Hdr, rr.Preference, rr.Exchanger}
}
......@@ -783,12 +854,17 @@ func (rr *NSEC3) copy() RR {
func (rr *NSEC3PARAM) copy() RR {
return &NSEC3PARAM{rr.Hdr, rr.Hash, rr.Flags, rr.Iterations, rr.SaltLength, rr.Salt}
}
func (rr *NULL) copy() RR {
return &NULL{rr.Hdr, rr.Data}
}
func (rr *OPENPGPKEY) copy() RR {
return &OPENPGPKEY{rr.Hdr, rr.PublicKey}
}
func (rr *OPT) copy() RR {
Option := make([]EDNS0, len(rr.Option))
copy(Option, rr.Option)
for i, e := range rr.Option {
Option[i] = e.copy()
}
return &OPT{rr.Hdr, Option}
}
func (rr *PTR) copy() RR {
......@@ -812,6 +888,9 @@ func (rr *RRSIG) copy() RR {
func (rr *RT) copy() RR {
return &RT{rr.Hdr, rr.Preference, rr.Host}
}
func (rr *SIG) copy() RR {
return &SIG{*rr.RRSIG.copy().(*RRSIG)}
}
func (rr *SMIMEA) copy() RR {
return &SMIMEA{rr.Hdr, rr.Usage, rr.Selector, rr.MatchingType, rr.Certificate}
}
......@@ -829,6 +908,13 @@ func (rr *SRV) copy() RR {
func (rr *SSHFP) copy() RR {
return &SSHFP{rr.Hdr, rr.Algorithm, rr.Type, rr.FingerPrint}
}
func (rr *SVCB) copy() RR {
Value := make([]SVCBKeyValue, len(rr.Value))
for i, e := range rr.Value {
Value[i] = e.copy()
}
return &SVCB{rr.Hdr, rr.Priority, rr.Target, Value}
}
func (rr *TA) copy() RR {
return &TA{rr.Hdr, rr.KeyTag, rr.Algorithm, rr.DigestType, rr.Digest}
}
......@@ -861,3 +947,6 @@ func (rr *URI) copy() RR {
func (rr *X25) copy() RR {
return &X25{rr.Hdr, rr.PSDNAddress}
}
func (rr *ZONEMD) copy() RR {
return &ZONEMD{rr.Hdr, rr.Serial, rr.Scheme, rr.Hash, rr.Digest}
}
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2017 The OpenZipkin Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
// Copyright 2022 The OpenZipkin Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package model
import (
"encoding/json"
"errors"
"time"
)
// ErrValidTimestampRequired error
var ErrValidTimestampRequired = errors.New("valid annotation timestamp required")
// Annotation associates an event that explains latency with a timestamp.
type Annotation struct {
Timestamp time.Time
Value string
}
// MarshalJSON implements custom JSON encoding
func (a *Annotation) MarshalJSON() ([]byte, error) {
return json.Marshal(&struct {
Timestamp int64 `json:"timestamp"`
Value string `json:"value"`
}{
Timestamp: a.Timestamp.Round(time.Microsecond).UnixNano() / 1e3,
Value: a.Value,
})
}
// UnmarshalJSON implements custom JSON decoding
func (a *Annotation) UnmarshalJSON(b []byte) error {
type Alias Annotation
annotation := &struct {
TimeStamp uint64 `json:"timestamp"`
*Alias
}{
Alias: (*Alias)(a),
}
if err := json.Unmarshal(b, &annotation); err != nil {
return err
}
if annotation.TimeStamp < 1 {
return ErrValidTimestampRequired
}
a.Timestamp = time.Unix(0, int64(annotation.TimeStamp)*1e3)
return nil
}
// Copyright 2022 The OpenZipkin Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
Package model contains the Zipkin V2 model which is used by the Zipkin Go
tracer implementation.
Third party instrumentation libraries can use the model and transport packages
found in this Zipkin Go library to directly interface with the Zipkin Server or
Zipkin Collectors without the need to use the tracer implementation itself.
*/
package model
// Copyright 2022 The OpenZipkin Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package model
import (
"encoding/json"
"net"
"strings"
)
// Endpoint holds the network context of a node in the service graph.
type Endpoint struct {
ServiceName string
IPv4 net.IP
IPv6 net.IP
Port uint16
}
// MarshalJSON exports our Endpoint into the correct format for the Zipkin V2 API.
func (e Endpoint) MarshalJSON() ([]byte, error) {
return json.Marshal(&struct {
ServiceName string `json:"serviceName,omitempty"`
IPv4 net.IP `json:"ipv4,omitempty"`
IPv6 net.IP `json:"ipv6,omitempty"`
Port uint16 `json:"port,omitempty"`
}{
strings.ToLower(e.ServiceName),
e.IPv4,
e.IPv6,
e.Port,
})
}
// Empty returns if all Endpoint properties are empty / unspecified.
func (e *Endpoint) Empty() bool {
return e == nil ||
(e.ServiceName == "" && e.Port == 0 && len(e.IPv4) == 0 && len(e.IPv6) == 0)
}