From ff7d4450818a0cfaaca639e20e0eb4cf7299bd05 Mon Sep 17 00:00:00 2001 From: Tom Thorogood Date: Sun, 2 Dec 2018 18:53:35 +1030 Subject: [PATCH] Avoid setting the Rdlength field when packing records (#859) * Avoid setting the Rdlength field when packing The offset of the end of the header is now returned from the RR.pack method, with the RDLENGTH record field being written in packRR. To maintain compatability with callers of PackRR who might be relying on this old behaviour, PackRR will now set rr.Header().Rdlength for external callers. Care must be taken by callers to ensure this won't cause a data-race. * Prevent panic if TestClientLocalAddress fails This came up during testing of the previous change. * Change style of overflow check in packRR --- client_test.go | 2 +- dns.go | 13 +- msg.go | 34 +- msg_generate.go | 15 +- msg_helpers.go | 20 +- privaterr.go | 13 +- rawmsg.go | 49 --- zmsg.go | 1090 +++++++++++++++++++++-------------------------- 8 files changed, 527 insertions(+), 709 deletions(-) delete mode 100644 rawmsg.go diff --git a/client_test.go b/client_test.go index edfd6b1d..b88c6f5c 100644 --- a/client_test.go +++ b/client_test.go @@ -93,7 +93,7 @@ func TestClientLocalAddress(t *testing.T) { t.Errorf("failed to get an valid answer\n%v", r) } if len(r.Extra) != 1 { - t.Errorf("failed to get additional answers\n%v", r) + t.Fatalf("failed to get additional answers\n%v", r) } txt := r.Extra[0].(*TXT) if txt == nil { diff --git a/dns.go b/dns.go index b6ab23cc..aefffa79 100644 --- a/dns.go +++ b/dns.go @@ -42,7 +42,7 @@ type RR interface { len(off int, compression map[string]struct{}) int // pack packs an RR into wire format. - pack([]byte, int, compressionMap, bool) (int, error) + pack(msg []byte, off int, compression compressionMap, compress bool) (headerEnd int, off1 int, err error) } // RR_Header is the header all DNS resource records share. @@ -84,19 +84,20 @@ func (h *RR_Header) len(off int, compression map[string]struct{}) int { // ToRFC3597 converts a known RR to the unknown RR representation from RFC 3597. func (rr *RFC3597) ToRFC3597(r RR) error { buf := make([]byte, Len(r)*2) - off, err := PackRR(r, buf, 0, nil, false) + headerEnd, off, err := packRR(r, buf, 0, compressionMap{}, false) if err != nil { return err } buf = buf[:off] - if int(r.Header().Rdlength) > off { - return ErrBuf - } - rfc3597, _, err := unpackRFC3597(*r.Header(), buf, off-int(r.Header().Rdlength)) + hdr := *r.Header() + hdr.Rdlength = uint16(off - headerEnd) + + rfc3597, _, err := unpackRFC3597(hdr, buf, headerEnd) if err != nil { return err } + *rr = *rfc3597.(*RFC3597) return nil } diff --git a/msg.go b/msg.go index fb97e5cb..33f14c48 100644 --- a/msg.go +++ b/msg.go @@ -619,23 +619,33 @@ func intToBytes(i *big.Int, length int) []byte { // PackRR packs a resource record rr into msg[off:]. // See PackDomainName for documentation about the compression. func PackRR(rr RR, msg []byte, off int, compression map[string]int, compress bool) (off1 int, err error) { - return packRR(rr, msg, off, compressionMap{ext: compression}, compress) + headerEnd, off1, err := packRR(rr, msg, off, compressionMap{ext: compression}, compress) + if err == nil { + // packRR no longer sets the Rdlength field on the rr, but + // callers might be expecting it so we set it here. + rr.Header().Rdlength = uint16(off1 - headerEnd) + } + return off1, err } -func packRR(rr RR, msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { +func packRR(rr RR, msg []byte, off int, compression compressionMap, compress bool) (headerEnd int, off1 int, err error) { if rr == nil { - return len(msg), &Error{err: "nil rr"} + return len(msg), len(msg), &Error{err: "nil rr"} } - off1, err = rr.pack(msg, off, compression, compress) + headerEnd, off1, err = rr.pack(msg, off, compression, compress) if err != nil { - return len(msg), err + return headerEnd, len(msg), err } - // TODO(miek): Not sure if this is needed? If removed we can remove rawmsg.go as well. - if rawSetRdlength(msg, off, off1) { - return off1, nil + + rdlength := off1 - headerEnd + if int(uint16(rdlength)) != rdlength { // overflow + return headerEnd, len(msg), ErrRdata } - return off, ErrRdata + + // The RDLENGTH field is the last field in the header and we set it here. + binary.BigEndian.PutUint16(msg[headerEnd-2:], uint16(rdlength)) + return headerEnd, off1, nil } // UnpackRR unpacks msg[off:] into an RR. @@ -821,19 +831,19 @@ func (dns *Msg) packBufferWithCompressionMap(buf []byte, compression compression } } for _, r := range dns.Answer { - off, err = packRR(r, msg, off, compression, compress) + _, off, err = packRR(r, msg, off, compression, compress) if err != nil { return nil, err } } for _, r := range dns.Ns { - off, err = packRR(r, msg, off, compression, compress) + _, off, err = packRR(r, msg, off, compression, compress) if err != nil { return nil, err } } for _, r := range dns.Extra { - off, err = packRR(r, msg, off, compression, compress) + _, off, err = packRR(r, msg, off, compression, compress) if err != nil { return nil, err } diff --git a/msg_generate.go b/msg_generate.go index f208ff82..86ed04fc 100644 --- a/msg_generate.go +++ b/msg_generate.go @@ -80,18 +80,17 @@ func main() { o := scope.Lookup(name) st, _ := getTypeStruct(o.Type(), scope) - fmt.Fprintf(b, "func (rr *%s) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) {\n", name) - fmt.Fprint(b, `off, err := rr.Hdr.pack(msg, off, compression, compress) + fmt.Fprintf(b, "func (rr *%s) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) {\n", name) + fmt.Fprint(b, `headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } -headerEnd := off `) for i := 1; i < st.NumFields(); i++ { o := func(s string) { fmt.Fprintf(b, s, st.Field(i).Name()) fmt.Fprint(b, `if err != nil { -return off, err +return headerEnd, off, err } `) } @@ -145,7 +144,7 @@ return off, err if rr.%s != "-" { off, err = packStringHex(rr.%s, msg, off) if err != nil { - return off, err + return headerEnd, off, err } } `, field, field) @@ -176,9 +175,7 @@ if rr.%s != "-" { log.Fatalln(name, st.Field(i).Name(), st.Tag(i)) } } - // We have packed everything, only now we know the rdlength of this RR - fmt.Fprintln(b, "rr.Header().Rdlength = uint16(off-headerEnd)") - fmt.Fprintln(b, "return off, nil }\n") + fmt.Fprintln(b, "return headerEnd, off, nil }\n") } fmt.Fprint(b, "// unpack*() functions\n\n") diff --git a/msg_helpers.go b/msg_helpers.go index 3a4d1e41..36345e16 100644 --- a/msg_helpers.go +++ b/msg_helpers.go @@ -101,32 +101,32 @@ func unpackHeader(msg []byte, off int) (rr RR_Header, off1 int, truncmsg []byte, // pack packs an RR header, returning the offset to the end of the header. // See PackDomainName for documentation about the compression. -func (hdr RR_Header) pack(msg []byte, off int, compression compressionMap, compress bool) (off1 int, err error) { +func (hdr RR_Header) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { if off == len(msg) { - return off, nil + return off, off, nil } - off, _, err = packDomainName(hdr.Name, msg, off, compression, compress) + off, _, err := packDomainName(hdr.Name, msg, off, compression, compress) if err != nil { - return len(msg), err + return off, len(msg), err } off, err = packUint16(hdr.Rrtype, msg, off) if err != nil { - return len(msg), err + return off, len(msg), err } off, err = packUint16(hdr.Class, msg, off) if err != nil { - return len(msg), err + return off, len(msg), err } off, err = packUint32(hdr.Ttl, msg, off) if err != nil { - return len(msg), err + return off, len(msg), err } - off, err = packUint16(hdr.Rdlength, msg, off) + off, err = packUint16(0, msg, off) // The RDLENGTH field will be set later in packRR. if err != nil { - return len(msg), err + return off, len(msg), err } - return off, nil + return off, off, nil } // helper helper functions. diff --git a/privaterr.go b/privaterr.go index 1591afbc..18355f9b 100644 --- a/privaterr.go +++ b/privaterr.go @@ -69,19 +69,18 @@ func (r *PrivateRR) copy() RR { } return rr } -func (r *PrivateRR) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := r.Hdr.pack(msg, off, compression, compress) + +func (r *PrivateRR) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := r.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return off, off, err } - headerEnd := off n, err := r.Data.Pack(msg[off:]) if err != nil { - return len(msg), err + return headerEnd, len(msg), err } off += n - r.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } // PrivateHandle registers a private resource record type. It requires diff --git a/rawmsg.go b/rawmsg.go deleted file mode 100644 index 6e21fba7..00000000 --- a/rawmsg.go +++ /dev/null @@ -1,49 +0,0 @@ -package dns - -import "encoding/binary" - -// rawSetRdlength sets the rdlength in the header of -// the RR. The offset 'off' must be positioned at the -// start of the header of the RR, 'end' must be the -// end of the RR. -func rawSetRdlength(msg []byte, off, end int) bool { - l := len(msg) -Loop: - for { - if off+1 > l { - return false - } - c := int(msg[off]) - off++ - switch c & 0xC0 { - case 0x00: - if c == 0x00 { - // End of the domainname - break Loop - } - if off+c > l { - return false - } - off += c - - case 0xC0: - // pointer, next byte included, ends domainname - off++ - break Loop - } - } - // The domainname has been seen, we at the start of the fixed part in the header. - // Type is 2 bytes, class is 2 bytes, ttl 4 and then 2 bytes for the length. - off += 2 + 2 + 4 - if off+2 > l { - return false - } - //off+1 is the end of the header, 'end' is the end of the rr - //so 'end' - 'off+2' is the length of the rdata - rdatalen := end - (off + 2) - if rdatalen > 0xFFFF { - return false - } - binary.BigEndian.PutUint16(msg[off:], uint16(rdatalen)) - return true -} diff --git a/zmsg.go b/zmsg.go index ca60f99f..3e93a782 100644 --- a/zmsg.go +++ b/zmsg.go @@ -4,1490 +4,1350 @@ package dns // pack*() functions -func (rr *A) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *A) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packDataA(rr.A, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *AAAA) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *AAAA) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packDataAAAA(rr.AAAA, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *AFSDB) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *AFSDB) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint16(rr.Subtype, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, _, err = packDomainName(rr.Hostname, msg, off, compression, false) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *ANY) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *ANY) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *AVC) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *AVC) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packStringTxt(rr.Txt, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *CAA) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *CAA) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint8(rr.Flag, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packString(rr.Tag, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packStringOctet(rr.Value, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *CDNSKEY) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *CDNSKEY) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint16(rr.Flags, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.Protocol, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.Algorithm, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packStringBase64(rr.PublicKey, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *CDS) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *CDS) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint16(rr.KeyTag, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.Algorithm, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.DigestType, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packStringHex(rr.Digest, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *CERT) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *CERT) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint16(rr.Type, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint16(rr.KeyTag, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.Algorithm, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packStringBase64(rr.Certificate, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *CNAME) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *CNAME) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, _, err = packDomainName(rr.Target, msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *CSYNC) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *CSYNC) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint32(rr.Serial, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint16(rr.Flags, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packDataNsec(rr.TypeBitMap, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *DHCID) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *DHCID) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packStringBase64(rr.Digest, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *DLV) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *DLV) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint16(rr.KeyTag, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.Algorithm, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.DigestType, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packStringHex(rr.Digest, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *DNAME) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *DNAME) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, _, err = packDomainName(rr.Target, msg, off, compression, false) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *DNSKEY) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *DNSKEY) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint16(rr.Flags, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.Protocol, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.Algorithm, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packStringBase64(rr.PublicKey, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *DS) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *DS) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint16(rr.KeyTag, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.Algorithm, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.DigestType, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packStringHex(rr.Digest, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *EID) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *EID) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packStringHex(rr.Endpoint, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *EUI48) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *EUI48) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint48(rr.Address, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *EUI64) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *EUI64) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint64(rr.Address, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *GID) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *GID) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint32(rr.Gid, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *GPOS) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *GPOS) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packString(rr.Longitude, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packString(rr.Latitude, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packString(rr.Altitude, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *HINFO) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *HINFO) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packString(rr.Cpu, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packString(rr.Os, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *HIP) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *HIP) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint8(rr.HitLength, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.PublicKeyAlgorithm, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint16(rr.PublicKeyLength, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packStringHex(rr.Hit, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packStringBase64(rr.PublicKey, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packDataDomainNames(rr.RendezvousServers, msg, off, compression, false) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *KEY) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *KEY) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint16(rr.Flags, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.Protocol, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.Algorithm, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packStringBase64(rr.PublicKey, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *KX) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *KX) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint16(rr.Preference, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, _, err = packDomainName(rr.Exchanger, msg, off, compression, false) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *L32) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *L32) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint16(rr.Preference, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packDataA(rr.Locator32, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *L64) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *L64) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint16(rr.Preference, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint64(rr.Locator64, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *LOC) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *LOC) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint8(rr.Version, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.Size, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.HorizPre, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.VertPre, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint32(rr.Latitude, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint32(rr.Longitude, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint32(rr.Altitude, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *LP) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *LP) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint16(rr.Preference, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, _, err = packDomainName(rr.Fqdn, msg, off, compression, false) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *MB) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *MB) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, _, err = packDomainName(rr.Mb, msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *MD) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *MD) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, _, err = packDomainName(rr.Md, msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *MF) pack(msg []byte, off int, compression compressionMap, 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) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, _, err = packDomainName(rr.Mf, msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *MG) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *MG) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, _, err = packDomainName(rr.Mg, msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *MINFO) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *MINFO) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, _, err = packDomainName(rr.Rmail, msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } off, _, err = packDomainName(rr.Email, msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *MR) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *MR) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, _, err = packDomainName(rr.Mr, msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *MX) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *MX) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint16(rr.Preference, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, _, err = packDomainName(rr.Mx, msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *NAPTR) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *NAPTR) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint16(rr.Order, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint16(rr.Preference, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packString(rr.Flags, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packString(rr.Service, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packString(rr.Regexp, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, _, err = packDomainName(rr.Replacement, msg, off, compression, false) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *NID) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *NID) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint16(rr.Preference, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint64(rr.NodeID, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *NIMLOC) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *NIMLOC) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packStringHex(rr.Locator, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *NINFO) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *NINFO) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packStringTxt(rr.ZSData, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *NS) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *NS) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, _, err = packDomainName(rr.Ns, msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *NSAPPTR) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *NSAPPTR) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, _, err = packDomainName(rr.Ptr, msg, off, compression, false) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *NSEC) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *NSEC) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, _, err = packDomainName(rr.NextDomain, msg, off, compression, false) if err != nil { - return off, err + return headerEnd, off, err } off, err = packDataNsec(rr.TypeBitMap, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *NSEC3) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *NSEC3) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint8(rr.Hash, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.Flags, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint16(rr.Iterations, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.SaltLength, msg, off) if err != nil { - return off, err + return headerEnd, off, err } // Only pack salt if value is not "-", i.e. empty if rr.Salt != "-" { off, err = packStringHex(rr.Salt, msg, off) if err != nil { - return off, err + return headerEnd, off, err } } off, err = packUint8(rr.HashLength, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packStringBase32(rr.NextDomain, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packDataNsec(rr.TypeBitMap, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *NSEC3PARAM) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *NSEC3PARAM) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint8(rr.Hash, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.Flags, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint16(rr.Iterations, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.SaltLength, msg, off) if err != nil { - return off, err + return headerEnd, off, err } // Only pack salt if value is not "-", i.e. empty if rr.Salt != "-" { off, err = packStringHex(rr.Salt, msg, off) if err != nil { - return off, err + return headerEnd, off, err } } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *OPENPGPKEY) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *OPENPGPKEY) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packStringBase64(rr.PublicKey, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *OPT) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *OPT) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packDataOpt(rr.Option, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *PTR) pack(msg []byte, off int, compression compressionMap, 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) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, _, err = packDomainName(rr.Ptr, msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *PX) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *PX) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint16(rr.Preference, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, _, err = packDomainName(rr.Map822, msg, off, compression, false) if err != nil { - return off, err + return headerEnd, off, err } off, _, err = packDomainName(rr.Mapx400, msg, off, compression, false) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *RFC3597) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *RFC3597) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packStringHex(rr.Rdata, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *RKEY) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *RKEY) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint16(rr.Flags, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.Protocol, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.Algorithm, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packStringBase64(rr.PublicKey, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *RP) pack(msg []byte, off int, compression compressionMap, 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) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, _, err = packDomainName(rr.Mbox, msg, off, compression, false) if err != nil { - return off, err + return headerEnd, off, err } off, _, err = packDomainName(rr.Txt, msg, off, compression, false) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *RRSIG) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *RRSIG) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint16(rr.TypeCovered, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.Algorithm, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.Labels, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint32(rr.OrigTtl, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint32(rr.Expiration, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint32(rr.Inception, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint16(rr.KeyTag, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, _, err = packDomainName(rr.SignerName, msg, off, compression, false) if err != nil { - return off, err + return headerEnd, off, err } off, err = packStringBase64(rr.Signature, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *RT) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *RT) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint16(rr.Preference, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, _, err = packDomainName(rr.Host, msg, off, compression, false) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *SIG) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *SIG) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint16(rr.TypeCovered, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.Algorithm, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.Labels, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint32(rr.OrigTtl, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint32(rr.Expiration, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint32(rr.Inception, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint16(rr.KeyTag, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, _, err = packDomainName(rr.SignerName, msg, off, compression, false) if err != nil { - return off, err + return headerEnd, off, err } off, err = packStringBase64(rr.Signature, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *SMIMEA) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *SMIMEA) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint8(rr.Usage, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.Selector, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.MatchingType, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packStringHex(rr.Certificate, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *SOA) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *SOA) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, _, err = packDomainName(rr.Ns, msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } off, _, err = packDomainName(rr.Mbox, msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint32(rr.Serial, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint32(rr.Refresh, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint32(rr.Retry, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint32(rr.Expire, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint32(rr.Minttl, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *SPF) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *SPF) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packStringTxt(rr.Txt, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *SRV) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *SRV) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint16(rr.Priority, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint16(rr.Weight, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint16(rr.Port, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, _, err = packDomainName(rr.Target, msg, off, compression, false) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *SSHFP) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *SSHFP) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint8(rr.Algorithm, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.Type, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packStringHex(rr.FingerPrint, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *TA) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *TA) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint16(rr.KeyTag, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.Algorithm, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.DigestType, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packStringHex(rr.Digest, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *TALINK) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *TALINK) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, _, err = packDomainName(rr.PreviousName, msg, off, compression, false) if err != nil { - return off, err + return headerEnd, off, err } off, _, err = packDomainName(rr.NextName, msg, off, compression, false) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *TKEY) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *TKEY) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, _, err = packDomainName(rr.Algorithm, msg, off, compression, false) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint32(rr.Inception, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint32(rr.Expiration, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint16(rr.Mode, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint16(rr.Error, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint16(rr.KeySize, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packStringHex(rr.Key, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint16(rr.OtherLen, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packStringHex(rr.OtherData, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *TLSA) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *TLSA) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint8(rr.Usage, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.Selector, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint8(rr.MatchingType, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packStringHex(rr.Certificate, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *TSIG) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *TSIG) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, _, err = packDomainName(rr.Algorithm, msg, off, compression, false) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint48(rr.TimeSigned, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint16(rr.Fudge, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint16(rr.MACSize, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packStringHex(rr.MAC, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint16(rr.OrigId, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint16(rr.Error, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint16(rr.OtherLen, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packStringHex(rr.OtherData, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *TXT) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *TXT) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packStringTxt(rr.Txt, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *UID) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *UID) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint32(rr.Uid, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *UINFO) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *UINFO) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packString(rr.Uinfo, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *URI) pack(msg []byte, off int, compression compressionMap, compress bool) (int, error) { - off, err := rr.Hdr.pack(msg, off, compression, compress) +func (rr *URI) pack(msg []byte, off int, compression compressionMap, compress bool) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packUint16(rr.Priority, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packUint16(rr.Weight, msg, off) if err != nil { - return off, err + return headerEnd, off, err } off, err = packStringOctet(rr.Target, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } -func (rr *X25) pack(msg []byte, off int, compression compressionMap, 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) (int, int, error) { + headerEnd, off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { - return off, err + return headerEnd, off, err } - headerEnd := off off, err = packString(rr.PSDNAddress, msg, off) if err != nil { - return off, err + return headerEnd, off, err } - rr.Header().Rdlength = uint16(off - headerEnd) - return off, nil + return headerEnd, off, nil } // unpack*() functions