|
|
@@ -273,25 +273,25 @@ type Resource struct {
|
|
|
// A ResourceBody is a DNS resource record minus the header.
|
|
|
type ResourceBody interface {
|
|
|
// pack packs a Resource except for its header.
|
|
|
- pack(msg []byte, compression map[string]int) ([]byte, error)
|
|
|
+ pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error)
|
|
|
|
|
|
// realType returns the actual type of the Resource. This is used to
|
|
|
// fill in the header Type field.
|
|
|
realType() Type
|
|
|
}
|
|
|
|
|
|
-func (r *Resource) pack(msg []byte, compression map[string]int) ([]byte, error) {
|
|
|
+func (r *Resource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
|
|
|
if r.Body == nil {
|
|
|
return msg, errNilResouceBody
|
|
|
}
|
|
|
oldMsg := msg
|
|
|
r.Header.Type = r.Body.realType()
|
|
|
- msg, length, err := r.Header.pack(msg, compression)
|
|
|
+ msg, length, err := r.Header.pack(msg, compression, compressionOff)
|
|
|
if err != nil {
|
|
|
return msg, &nestedError{"ResourceHeader", err}
|
|
|
}
|
|
|
preLen := len(msg)
|
|
|
- msg, err = r.Body.pack(msg, compression)
|
|
|
+ msg, err = r.Body.pack(msg, compression, compressionOff)
|
|
|
if err != nil {
|
|
|
return msg, &nestedError{"content", err}
|
|
|
}
|
|
|
@@ -852,6 +852,7 @@ func (m *Message) AppendPack(b []byte) ([]byte, error) {
|
|
|
h.authorities = uint16(len(m.Authorities))
|
|
|
h.additionals = uint16(len(m.Additionals))
|
|
|
|
|
|
+ compressionOff := len(b)
|
|
|
msg := h.pack(b)
|
|
|
|
|
|
// RFC 1035 allows (but does not require) compression for packing. RFC
|
|
|
@@ -866,25 +867,25 @@ func (m *Message) AppendPack(b []byte) ([]byte, error) {
|
|
|
|
|
|
for i := range m.Questions {
|
|
|
var err error
|
|
|
- if msg, err = m.Questions[i].pack(msg, compression); err != nil {
|
|
|
+ if msg, err = m.Questions[i].pack(msg, compression, compressionOff); err != nil {
|
|
|
return nil, &nestedError{"packing Question", err}
|
|
|
}
|
|
|
}
|
|
|
for i := range m.Answers {
|
|
|
var err error
|
|
|
- if msg, err = m.Answers[i].pack(msg, compression); err != nil {
|
|
|
+ if msg, err = m.Answers[i].pack(msg, compression, compressionOff); err != nil {
|
|
|
return nil, &nestedError{"packing Answer", err}
|
|
|
}
|
|
|
}
|
|
|
for i := range m.Authorities {
|
|
|
var err error
|
|
|
- if msg, err = m.Authorities[i].pack(msg, compression); err != nil {
|
|
|
+ if msg, err = m.Authorities[i].pack(msg, compression, compressionOff); err != nil {
|
|
|
return nil, &nestedError{"packing Authority", err}
|
|
|
}
|
|
|
}
|
|
|
for i := range m.Additionals {
|
|
|
var err error
|
|
|
- if msg, err = m.Additionals[i].pack(msg, compression); err != nil {
|
|
|
+ if msg, err = m.Additionals[i].pack(msg, compression, compressionOff); err != nil {
|
|
|
return nil, &nestedError{"packing Additional", err}
|
|
|
}
|
|
|
}
|
|
|
@@ -893,36 +894,69 @@ func (m *Message) AppendPack(b []byte) ([]byte, error) {
|
|
|
}
|
|
|
|
|
|
// A Builder allows incrementally packing a DNS message.
|
|
|
+//
|
|
|
+// Example usage:
|
|
|
+// buf := make([]byte, 2, 514)
|
|
|
+// b := NewBuilder(buf, Header{...})
|
|
|
+// b.EnableCompression()
|
|
|
+// // Optionally start a section and add things to that section.
|
|
|
+// // Repeat adding sections as necessary.
|
|
|
+// buf, err := b.Finish()
|
|
|
+// // If err is nil, buf[2:] will contain the built bytes.
|
|
|
type Builder struct {
|
|
|
- msg []byte
|
|
|
- header header
|
|
|
- section section
|
|
|
+ // msg is the storage for the message being built.
|
|
|
+ msg []byte
|
|
|
+
|
|
|
+ // section keeps track of the current section being built.
|
|
|
+ section section
|
|
|
+
|
|
|
+ // header keeps track of what should go in the header when Finish is
|
|
|
+ // called.
|
|
|
+ header header
|
|
|
+
|
|
|
+ // start is the starting index of the bytes allocated in msg for header.
|
|
|
+ start int
|
|
|
+
|
|
|
+ // compression is a mapping from name suffixes to their starting index
|
|
|
+ // in msg.
|
|
|
compression map[string]int
|
|
|
}
|
|
|
|
|
|
-// Start initializes the builder.
|
|
|
+// NewBuilder creates a new builder with compression disabled.
|
|
|
//
|
|
|
-// buf is optional (nil is fine), but if provided, Start takes ownership of buf.
|
|
|
-func (b *Builder) Start(buf []byte, h Header) {
|
|
|
- b.StartWithoutCompression(buf, h)
|
|
|
- b.compression = map[string]int{}
|
|
|
+// Note: Most users will want to immediately enable compression with the
|
|
|
+// EnableCompression method. See that method's comment for why you may or may
|
|
|
+// not want to enable compression.
|
|
|
+//
|
|
|
+// The DNS message is appended to the provided initial buffer buf (which may be
|
|
|
+// nil) as it is built. The final message is returned by the (*Builder).Finish
|
|
|
+// method, which may return the same underlying array if there was sufficient
|
|
|
+// capacity in the slice.
|
|
|
+func NewBuilder(buf []byte, h Header) Builder {
|
|
|
+ if buf == nil {
|
|
|
+ buf = make([]byte, 0, packStartingCap)
|
|
|
+ }
|
|
|
+ b := Builder{msg: buf, start: len(buf)}
|
|
|
+ b.header.id, b.header.bits = h.pack()
|
|
|
+ var hb [headerLen]byte
|
|
|
+ b.msg = append(b.msg, hb[:]...)
|
|
|
+ b.section = sectionHeader
|
|
|
+ return b
|
|
|
}
|
|
|
|
|
|
-// StartWithoutCompression initializes the builder with compression disabled.
|
|
|
+// EnableCompression enables compression in the Builder.
|
|
|
//
|
|
|
-// This avoids compression related allocations, but can result in larger message
|
|
|
-// sizes. Be careful with this mode as it can cause messages to exceed the UDP
|
|
|
-// size limit.
|
|
|
+// Leaving compression disabled avoids compression related allocations, but can
|
|
|
+// result in larger message sizes. Be careful with this mode as it can cause
|
|
|
+// messages to exceed the UDP size limit.
|
|
|
//
|
|
|
-// buf is optional (nil is fine), but if provided, Start takes ownership of buf.
|
|
|
-func (b *Builder) StartWithoutCompression(buf []byte, h Header) {
|
|
|
- *b = Builder{msg: buf}
|
|
|
- b.header.id, b.header.bits = h.pack()
|
|
|
- if cap(b.msg) < headerLen {
|
|
|
- b.msg = make([]byte, 0, packStartingCap)
|
|
|
- }
|
|
|
- b.msg = b.msg[:headerLen]
|
|
|
- b.section = sectionHeader
|
|
|
+// According to RFC 1035, section 4.1.4, the use of compression is optional, but
|
|
|
+// all implementations must accept both compressed and uncompressed DNS
|
|
|
+// messages.
|
|
|
+//
|
|
|
+// Compression should be enabled before any sections are added for best results.
|
|
|
+func (b *Builder) EnableCompression() {
|
|
|
+ b.compression = map[string]int{}
|
|
|
}
|
|
|
|
|
|
func (b *Builder) startCheck(s section) error {
|
|
|
@@ -1003,7 +1037,7 @@ func (b *Builder) Question(q Question) error {
|
|
|
if b.section > sectionQuestions {
|
|
|
return ErrSectionDone
|
|
|
}
|
|
|
- msg, err := q.pack(b.msg, b.compression)
|
|
|
+ msg, err := q.pack(b.msg, b.compression, b.start)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
@@ -1030,12 +1064,12 @@ func (b *Builder) CNAMEResource(h ResourceHeader, r CNAMEResource) error {
|
|
|
return err
|
|
|
}
|
|
|
h.Type = r.realType()
|
|
|
- msg, length, err := h.pack(b.msg, b.compression)
|
|
|
+ msg, length, err := h.pack(b.msg, b.compression, b.start)
|
|
|
if err != nil {
|
|
|
return &nestedError{"ResourceHeader", err}
|
|
|
}
|
|
|
preLen := len(msg)
|
|
|
- if msg, err = r.pack(msg, b.compression); err != nil {
|
|
|
+ if msg, err = r.pack(msg, b.compression, b.start); err != nil {
|
|
|
return &nestedError{"CNAMEResource body", err}
|
|
|
}
|
|
|
if err := h.fixLen(msg, length, preLen); err != nil {
|
|
|
@@ -1054,12 +1088,12 @@ func (b *Builder) MXResource(h ResourceHeader, r MXResource) error {
|
|
|
return err
|
|
|
}
|
|
|
h.Type = r.realType()
|
|
|
- msg, length, err := h.pack(b.msg, b.compression)
|
|
|
+ msg, length, err := h.pack(b.msg, b.compression, b.start)
|
|
|
if err != nil {
|
|
|
return &nestedError{"ResourceHeader", err}
|
|
|
}
|
|
|
preLen := len(msg)
|
|
|
- if msg, err = r.pack(msg, b.compression); err != nil {
|
|
|
+ if msg, err = r.pack(msg, b.compression, b.start); err != nil {
|
|
|
return &nestedError{"MXResource body", err}
|
|
|
}
|
|
|
if err := h.fixLen(msg, length, preLen); err != nil {
|
|
|
@@ -1078,12 +1112,12 @@ func (b *Builder) NSResource(h ResourceHeader, r NSResource) error {
|
|
|
return err
|
|
|
}
|
|
|
h.Type = r.realType()
|
|
|
- msg, length, err := h.pack(b.msg, b.compression)
|
|
|
+ msg, length, err := h.pack(b.msg, b.compression, b.start)
|
|
|
if err != nil {
|
|
|
return &nestedError{"ResourceHeader", err}
|
|
|
}
|
|
|
preLen := len(msg)
|
|
|
- if msg, err = r.pack(msg, b.compression); err != nil {
|
|
|
+ if msg, err = r.pack(msg, b.compression, b.start); err != nil {
|
|
|
return &nestedError{"NSResource body", err}
|
|
|
}
|
|
|
if err := h.fixLen(msg, length, preLen); err != nil {
|
|
|
@@ -1102,12 +1136,12 @@ func (b *Builder) PTRResource(h ResourceHeader, r PTRResource) error {
|
|
|
return err
|
|
|
}
|
|
|
h.Type = r.realType()
|
|
|
- msg, length, err := h.pack(b.msg, b.compression)
|
|
|
+ msg, length, err := h.pack(b.msg, b.compression, b.start)
|
|
|
if err != nil {
|
|
|
return &nestedError{"ResourceHeader", err}
|
|
|
}
|
|
|
preLen := len(msg)
|
|
|
- if msg, err = r.pack(msg, b.compression); err != nil {
|
|
|
+ if msg, err = r.pack(msg, b.compression, b.start); err != nil {
|
|
|
return &nestedError{"PTRResource body", err}
|
|
|
}
|
|
|
if err := h.fixLen(msg, length, preLen); err != nil {
|
|
|
@@ -1126,12 +1160,12 @@ func (b *Builder) SOAResource(h ResourceHeader, r SOAResource) error {
|
|
|
return err
|
|
|
}
|
|
|
h.Type = r.realType()
|
|
|
- msg, length, err := h.pack(b.msg, b.compression)
|
|
|
+ msg, length, err := h.pack(b.msg, b.compression, b.start)
|
|
|
if err != nil {
|
|
|
return &nestedError{"ResourceHeader", err}
|
|
|
}
|
|
|
preLen := len(msg)
|
|
|
- if msg, err = r.pack(msg, b.compression); err != nil {
|
|
|
+ if msg, err = r.pack(msg, b.compression, b.start); err != nil {
|
|
|
return &nestedError{"SOAResource body", err}
|
|
|
}
|
|
|
if err := h.fixLen(msg, length, preLen); err != nil {
|
|
|
@@ -1150,12 +1184,12 @@ func (b *Builder) TXTResource(h ResourceHeader, r TXTResource) error {
|
|
|
return err
|
|
|
}
|
|
|
h.Type = r.realType()
|
|
|
- msg, length, err := h.pack(b.msg, b.compression)
|
|
|
+ msg, length, err := h.pack(b.msg, b.compression, b.start)
|
|
|
if err != nil {
|
|
|
return &nestedError{"ResourceHeader", err}
|
|
|
}
|
|
|
preLen := len(msg)
|
|
|
- if msg, err = r.pack(msg, b.compression); err != nil {
|
|
|
+ if msg, err = r.pack(msg, b.compression, b.start); err != nil {
|
|
|
return &nestedError{"TXTResource body", err}
|
|
|
}
|
|
|
if err := h.fixLen(msg, length, preLen); err != nil {
|
|
|
@@ -1174,12 +1208,12 @@ func (b *Builder) SRVResource(h ResourceHeader, r SRVResource) error {
|
|
|
return err
|
|
|
}
|
|
|
h.Type = r.realType()
|
|
|
- msg, length, err := h.pack(b.msg, b.compression)
|
|
|
+ msg, length, err := h.pack(b.msg, b.compression, b.start)
|
|
|
if err != nil {
|
|
|
return &nestedError{"ResourceHeader", err}
|
|
|
}
|
|
|
preLen := len(msg)
|
|
|
- if msg, err = r.pack(msg, b.compression); err != nil {
|
|
|
+ if msg, err = r.pack(msg, b.compression, b.start); err != nil {
|
|
|
return &nestedError{"SRVResource body", err}
|
|
|
}
|
|
|
if err := h.fixLen(msg, length, preLen); err != nil {
|
|
|
@@ -1198,12 +1232,12 @@ func (b *Builder) AResource(h ResourceHeader, r AResource) error {
|
|
|
return err
|
|
|
}
|
|
|
h.Type = r.realType()
|
|
|
- msg, length, err := h.pack(b.msg, b.compression)
|
|
|
+ msg, length, err := h.pack(b.msg, b.compression, b.start)
|
|
|
if err != nil {
|
|
|
return &nestedError{"ResourceHeader", err}
|
|
|
}
|
|
|
preLen := len(msg)
|
|
|
- if msg, err = r.pack(msg, b.compression); err != nil {
|
|
|
+ if msg, err = r.pack(msg, b.compression, b.start); err != nil {
|
|
|
return &nestedError{"AResource body", err}
|
|
|
}
|
|
|
if err := h.fixLen(msg, length, preLen); err != nil {
|
|
|
@@ -1222,12 +1256,12 @@ func (b *Builder) AAAAResource(h ResourceHeader, r AAAAResource) error {
|
|
|
return err
|
|
|
}
|
|
|
h.Type = r.realType()
|
|
|
- msg, length, err := h.pack(b.msg, b.compression)
|
|
|
+ msg, length, err := h.pack(b.msg, b.compression, b.start)
|
|
|
if err != nil {
|
|
|
return &nestedError{"ResourceHeader", err}
|
|
|
}
|
|
|
preLen := len(msg)
|
|
|
- if msg, err = r.pack(msg, b.compression); err != nil {
|
|
|
+ if msg, err = r.pack(msg, b.compression, b.start); err != nil {
|
|
|
return &nestedError{"AAAAResource body", err}
|
|
|
}
|
|
|
if err := h.fixLen(msg, length, preLen); err != nil {
|
|
|
@@ -1246,7 +1280,8 @@ func (b *Builder) Finish() ([]byte, error) {
|
|
|
return nil, ErrNotStarted
|
|
|
}
|
|
|
b.section = sectionDone
|
|
|
- b.header.pack(b.msg[:0])
|
|
|
+ // Space for the header was allocated in NewBuilder.
|
|
|
+ b.header.pack(b.msg[b.start:b.start])
|
|
|
return b.msg, nil
|
|
|
}
|
|
|
|
|
|
@@ -1279,9 +1314,9 @@ type ResourceHeader struct {
|
|
|
// pack packs all of the fields in a ResourceHeader except for the length. The
|
|
|
// length bytes are returned as a slice so they can be filled in after the rest
|
|
|
// of the Resource has been packed.
|
|
|
-func (h *ResourceHeader) pack(oldMsg []byte, compression map[string]int) (msg []byte, length []byte, err error) {
|
|
|
+func (h *ResourceHeader) pack(oldMsg []byte, compression map[string]int, compressionOff int) (msg []byte, length []byte, err error) {
|
|
|
msg = oldMsg
|
|
|
- if msg, err = h.Name.pack(msg, compression); err != nil {
|
|
|
+ if msg, err = h.Name.pack(msg, compression, compressionOff); err != nil {
|
|
|
return oldMsg, nil, &nestedError{"Name", err}
|
|
|
}
|
|
|
msg = packType(msg, h.Type)
|
|
|
@@ -1506,7 +1541,7 @@ func (n Name) String() string {
|
|
|
//
|
|
|
// The compression map will be updated with new domain suffixes. If compression
|
|
|
// is nil, compression will not be used.
|
|
|
-func (n *Name) pack(msg []byte, compression map[string]int) ([]byte, error) {
|
|
|
+func (n *Name) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
|
|
|
oldMsg := msg
|
|
|
|
|
|
// Add a trailing dot to canonicalize name.
|
|
|
@@ -1558,7 +1593,7 @@ func (n *Name) pack(msg []byte, compression map[string]int) ([]byte, error) {
|
|
|
// Miss. Add the suffix to the compression table if the
|
|
|
// offset can be stored in the available 14 bytes.
|
|
|
if len(msg) <= int(^uint16(0)>>2) {
|
|
|
- compression[string(n.Data[i:])] = len(msg)
|
|
|
+ compression[string(n.Data[i:])] = len(msg) - compressionOff
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -1681,8 +1716,8 @@ type Question struct {
|
|
|
Class Class
|
|
|
}
|
|
|
|
|
|
-func (q *Question) pack(msg []byte, compression map[string]int) ([]byte, error) {
|
|
|
- msg, err := q.Name.pack(msg, compression)
|
|
|
+func (q *Question) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
|
|
|
+ msg, err := q.Name.pack(msg, compression, compressionOff)
|
|
|
if err != nil {
|
|
|
return msg, &nestedError{"Name", err}
|
|
|
}
|
|
|
@@ -1761,8 +1796,8 @@ func (r *CNAMEResource) realType() Type {
|
|
|
return TypeCNAME
|
|
|
}
|
|
|
|
|
|
-func (r *CNAMEResource) pack(msg []byte, compression map[string]int) ([]byte, error) {
|
|
|
- return r.CNAME.pack(msg, compression)
|
|
|
+func (r *CNAMEResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
|
|
|
+ return r.CNAME.pack(msg, compression, compressionOff)
|
|
|
}
|
|
|
|
|
|
func unpackCNAMEResource(msg []byte, off int) (CNAMEResource, error) {
|
|
|
@@ -1783,10 +1818,10 @@ func (r *MXResource) realType() Type {
|
|
|
return TypeMX
|
|
|
}
|
|
|
|
|
|
-func (r *MXResource) pack(msg []byte, compression map[string]int) ([]byte, error) {
|
|
|
+func (r *MXResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
|
|
|
oldMsg := msg
|
|
|
msg = packUint16(msg, r.Pref)
|
|
|
- msg, err := r.MX.pack(msg, compression)
|
|
|
+ msg, err := r.MX.pack(msg, compression, compressionOff)
|
|
|
if err != nil {
|
|
|
return oldMsg, &nestedError{"MXResource.MX", err}
|
|
|
}
|
|
|
@@ -1814,8 +1849,8 @@ func (r *NSResource) realType() Type {
|
|
|
return TypeNS
|
|
|
}
|
|
|
|
|
|
-func (r *NSResource) pack(msg []byte, compression map[string]int) ([]byte, error) {
|
|
|
- return r.NS.pack(msg, compression)
|
|
|
+func (r *NSResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
|
|
|
+ return r.NS.pack(msg, compression, compressionOff)
|
|
|
}
|
|
|
|
|
|
func unpackNSResource(msg []byte, off int) (NSResource, error) {
|
|
|
@@ -1835,8 +1870,8 @@ func (r *PTRResource) realType() Type {
|
|
|
return TypePTR
|
|
|
}
|
|
|
|
|
|
-func (r *PTRResource) pack(msg []byte, compression map[string]int) ([]byte, error) {
|
|
|
- return r.PTR.pack(msg, compression)
|
|
|
+func (r *PTRResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
|
|
|
+ return r.PTR.pack(msg, compression, compressionOff)
|
|
|
}
|
|
|
|
|
|
func unpackPTRResource(msg []byte, off int) (PTRResource, error) {
|
|
|
@@ -1866,13 +1901,13 @@ func (r *SOAResource) realType() Type {
|
|
|
return TypeSOA
|
|
|
}
|
|
|
|
|
|
-func (r *SOAResource) pack(msg []byte, compression map[string]int) ([]byte, error) {
|
|
|
+func (r *SOAResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
|
|
|
oldMsg := msg
|
|
|
- msg, err := r.NS.pack(msg, compression)
|
|
|
+ msg, err := r.NS.pack(msg, compression, compressionOff)
|
|
|
if err != nil {
|
|
|
return oldMsg, &nestedError{"SOAResource.NS", err}
|
|
|
}
|
|
|
- msg, err = r.MBox.pack(msg, compression)
|
|
|
+ msg, err = r.MBox.pack(msg, compression, compressionOff)
|
|
|
if err != nil {
|
|
|
return oldMsg, &nestedError{"SOAResource.MBox", err}
|
|
|
}
|
|
|
@@ -1925,7 +1960,7 @@ func (r *TXTResource) realType() Type {
|
|
|
return TypeTXT
|
|
|
}
|
|
|
|
|
|
-func (r *TXTResource) pack(msg []byte, compression map[string]int) ([]byte, error) {
|
|
|
+func (r *TXTResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
|
|
|
return packText(msg, r.Txt), nil
|
|
|
}
|
|
|
|
|
|
@@ -1959,12 +1994,12 @@ func (r *SRVResource) realType() Type {
|
|
|
return TypeSRV
|
|
|
}
|
|
|
|
|
|
-func (r *SRVResource) pack(msg []byte, compression map[string]int) ([]byte, error) {
|
|
|
+func (r *SRVResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
|
|
|
oldMsg := msg
|
|
|
msg = packUint16(msg, r.Priority)
|
|
|
msg = packUint16(msg, r.Weight)
|
|
|
msg = packUint16(msg, r.Port)
|
|
|
- msg, err := r.Target.pack(msg, nil)
|
|
|
+ msg, err := r.Target.pack(msg, nil, compressionOff)
|
|
|
if err != nil {
|
|
|
return oldMsg, &nestedError{"SRVResource.Target", err}
|
|
|
}
|
|
|
@@ -2000,7 +2035,7 @@ func (r *AResource) realType() Type {
|
|
|
return TypeA
|
|
|
}
|
|
|
|
|
|
-func (r *AResource) pack(msg []byte, compression map[string]int) ([]byte, error) {
|
|
|
+func (r *AResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
|
|
|
return packBytes(msg, r.A[:]), nil
|
|
|
}
|
|
|
|
|
|
@@ -2021,7 +2056,7 @@ func (r *AAAAResource) realType() Type {
|
|
|
return TypeAAAA
|
|
|
}
|
|
|
|
|
|
-func (r *AAAAResource) pack(msg []byte, compression map[string]int) ([]byte, error) {
|
|
|
+func (r *AAAAResource) pack(msg []byte, compression map[string]int, compressionOff int) ([]byte, error) {
|
|
|
return packBytes(msg, r.AAAA[:]), nil
|
|
|
}
|
|
|
|