Use dLen for domain name length

This commit is contained in:
Miek Gieben 2014-02-12 12:50:16 +00:00
parent 31102c38b7
commit b595183834
3 changed files with 47 additions and 38 deletions

2
dns.go
View File

@ -166,7 +166,7 @@ func (h *RR_Header) String() string {
}
func (h *RR_Header) len() int {
l := len(h.Name) + 1
l := dLen(h.Name)
l += 10 // rrtype(2) + class(2) + ttl(4) + rdlength(2)
return l
}

View File

@ -280,17 +280,17 @@ func TestMsgLenTest2(t *testing.T) {
var testMessages = []string{
// google.com. IN A?
"064e81800001000b0004000506676f6f676c6503636f6d0000010001c00c00010001000000050004adc22986c00c00010001000000050004adc22987c00c00010001000000050004adc22988c00c00010001000000050004adc22989c00c00010001000000050004adc2298ec00c00010001000000050004adc22980c00c00010001000000050004adc22981c00c00010001000000050004adc22982c00c00010001000000050004adc22983c00c00010001000000050004adc22984c00c00010001000000050004adc22985c00c00020001000000050006036e7331c00cc00c00020001000000050006036e7332c00cc00c00020001000000050006036e7333c00cc00c00020001000000050006036e7334c00cc0d800010001000000050004d8ef200ac0ea00010001000000050004d8ef220ac0fc00010001000000050004d8ef240ac10e00010001000000050004d8ef260a0000290500000000050000",
// amazon.com. IN A?
// amazon.com. IN A? (reply has no EDNS0 record)
// TODO(miek): this one *hits* the mark exactly, need to find out why
// "6de1818000010004000a000806616d617a6f6e03636f6d0000010001c00c000100010000000500044815c2d4c00c000100010000000500044815d7e8c00c00010001000000050004b02062a6c00c00010001000000050004cdfbf236c00c000200010000000500140570646e733408756c747261646e73036f726700c00c000200010000000500150570646e733508756c747261646e7304696e666f00c00c000200010000000500160570646e733608756c747261646e7302636f02756b00c00c00020001000000050014036e7331037033310664796e656374036e657400c00c00020001000000050006036e7332c0cfc00c00020001000000050006036e7333c0cfc00c00020001000000050006036e7334c0cfc00c000200010000000500110570646e733108756c747261646e73c0dac00c000200010000000500080570646e7332c127c00c000200010000000500080570646e7333c06ec0cb00010001000000050004d04e461fc0eb00010001000000050004cc0dfa1fc0fd00010001000000050004d04e471fc10f00010001000000050004cc0dfb1fc12100010001000000050004cc4a6c01c121001c000100000005001020010502f3ff00000000000000000001c13e00010001000000050004cc4a6d01c13e001c0001000000050010261000a1101400000000000000000001",
"6de1818000010004000a000806616d617a6f6e03636f6d0000010001c00c000100010000000500044815c2d4c00c000100010000000500044815d7e8c00c00010001000000050004b02062a6c00c00010001000000050004cdfbf236c00c000200010000000500140570646e733408756c747261646e73036f726700c00c000200010000000500150570646e733508756c747261646e7304696e666f00c00c000200010000000500160570646e733608756c747261646e7302636f02756b00c00c00020001000000050014036e7331037033310664796e656374036e657400c00c00020001000000050006036e7332c0cfc00c00020001000000050006036e7333c0cfc00c00020001000000050006036e7334c0cfc00c000200010000000500110570646e733108756c747261646e73c0dac00c000200010000000500080570646e7332c127c00c000200010000000500080570646e7333c06ec0cb00010001000000050004d04e461fc0eb00010001000000050004cc0dfa1fc0fd00010001000000050004d04e471fc10f00010001000000050004cc0dfb1fc12100010001000000050004cc4a6c01c121001c000100000005001020010502f3ff00000000000000000001c13e00010001000000050004cc4a6d01c13e001c0001000000050010261000a1101400000000000000000001",
// yahoo.com. IN A?
"fc2d81800001000300070008057961686f6f03636f6d0000010001c00c00010001000000050004628afd6dc00c00010001000000050004628bb718c00c00010001000000050004cebe242dc00c00020001000000050006036e7336c00cc00c00020001000000050006036e7338c00cc00c00020001000000050006036e7331c00cc00c00020001000000050006036e7332c00cc00c00020001000000050006036e7333c00cc00c00020001000000050006036e7334c00cc00c00020001000000050006036e7335c00cc07b0001000100000005000444b48310c08d00010001000000050004448eff10c09f00010001000000050004cb54dd35c0b100010001000000050004628a0b9dc0c30001000100000005000477a0f77cc05700010001000000050004ca2bdfaac06900010001000000050004caa568160000290500000000050000",
//"fc2d81800001000300070008057961686f6f03636f6d0000010001c00c00010001000000050004628afd6dc00c00010001000000050004628bb718c00c00010001000000050004cebe242dc00c00020001000000050006036e7336c00cc00c00020001000000050006036e7338c00cc00c00020001000000050006036e7331c00cc00c00020001000000050006036e7332c00cc00c00020001000000050006036e7333c00cc00c00020001000000050006036e7334c00cc00c00020001000000050006036e7335c00cc07b0001000100000005000444b48310c08d00010001000000050004448eff10c09f00010001000000050004cb54dd35c0b100010001000000050004628a0b9dc0c30001000100000005000477a0f77cc05700010001000000050004ca2bdfaac06900010001000000050004caa568160000290500000000050000",
// microsoft.com. IN A?
"f4368180000100020005000b096d6963726f736f667403636f6d0000010001c00c0001000100000005000440040b25c00c0001000100000005000441373ac9c00c0002000100000005000e036e7331046d736674036e657400c00c00020001000000050006036e7332c04fc00c00020001000000050006036e7333c04fc00c00020001000000050006036e7334c04fc00c00020001000000050006036e7335c04fc04b000100010000000500044137253ec04b001c00010000000500102a010111200500000000000000010001c0650001000100000005000440043badc065001c00010000000500102a010111200600060000000000010001c07700010001000000050004d5c7b435c077001c00010000000500102a010111202000000000000000010001c08900010001000000050004cf2e4bfec089001c00010000000500102404f800200300000000000000010001c09b000100010000000500044137e28cc09b001c00010000000500102a010111200f000100000000000100010000290500000000050000",
//"f4368180000100020005000b096d6963726f736f667403636f6d0000010001c00c0001000100000005000440040b25c00c0001000100000005000441373ac9c00c0002000100000005000e036e7331046d736674036e657400c00c00020001000000050006036e7332c04fc00c00020001000000050006036e7333c04fc00c00020001000000050006036e7334c04fc00c00020001000000050006036e7335c04fc04b000100010000000500044137253ec04b001c00010000000500102a010111200500000000000000010001c0650001000100000005000440043badc065001c00010000000500102a010111200600060000000000010001c07700010001000000050004d5c7b435c077001c00010000000500102a010111202000000000000000010001c08900010001000000050004cf2e4bfec089001c00010000000500102404f800200300000000000000010001c09b000100010000000500044137e28cc09b001c00010000000500102a010111200f000100000000000100010000290500000000050000",
// google.com. IN MX?
"724b8180000100050004000b06676f6f676c6503636f6d00000f0001c00c000f000100000005000c000a056173706d78016cc00cc00c000f0001000000050009001404616c7431c02ac00c000f0001000000050009001e04616c7432c02ac00c000f0001000000050009002804616c7433c02ac00c000f0001000000050009003204616c7434c02ac00c00020001000000050006036e7332c00cc00c00020001000000050006036e7333c00cc00c00020001000000050006036e7334c00cc00c00020001000000050006036e7331c00cc02a00010001000000050004adc2421bc02a001c00010000000500102a00145040080c01000000000000001bc04200010001000000050004adc2461bc05700010001000000050004adc2451bc06c000100010000000500044a7d8f1bc081000100010000000500044a7d191bc0ca00010001000000050004d8ef200ac09400010001000000050004d8ef220ac0a600010001000000050004d8ef240ac0b800010001000000050004d8ef260a0000290500000000050000",
//"724b8180000100050004000b06676f6f676c6503636f6d00000f0001c00c000f000100000005000c000a056173706d78016cc00cc00c000f0001000000050009001404616c7431c02ac00c000f0001000000050009001e04616c7432c02ac00c000f0001000000050009002804616c7433c02ac00c000f0001000000050009003204616c7434c02ac00c00020001000000050006036e7332c00cc00c00020001000000050006036e7333c00cc00c00020001000000050006036e7334c00cc00c00020001000000050006036e7331c00cc02a00010001000000050004adc2421bc02a001c00010000000500102a00145040080c01000000000000001bc04200010001000000050004adc2461bc05700010001000000050004adc2451bc06c000100010000000500044a7d8f1bc081000100010000000500044a7d191bc0ca00010001000000050004d8ef200ac09400010001000000050004d8ef220ac0a600010001000000050004d8ef240ac0b800010001000000050004d8ef260a0000290500000000050000",
// reddit.com. IN A?
"12b98180000100080000000c0672656464697403636f6d0000020001c00c0002000100000005000f046175733204616b616d036e657400c00c000200010000000500070475736534c02dc00c000200010000000500070475737733c02dc00c000200010000000500070475737735c02dc00c00020001000000050008056173696131c02dc00c00020001000000050008056173696139c02dc00c00020001000000050008056e73312d31c02dc00c0002000100000005000a076e73312d313935c02dc02800010001000000050004c30a242ec04300010001000000050004451f1d39c05600010001000000050004451f3bc7c0690001000100000005000460073240c07c000100010000000500046007fb81c090000100010000000500047c283484c090001c00010000000500102a0226f0006700000000000000000064c0a400010001000000050004c16c5b01c0a4001c000100000005001026001401000200000000000000000001c0b800010001000000050004c16c5bc3c0b8001c0001000000050010260014010002000000000000000000c30000290500000000050000",
//"12b98180000100080000000c0672656464697403636f6d0000020001c00c0002000100000005000f046175733204616b616d036e657400c00c000200010000000500070475736534c02dc00c000200010000000500070475737733c02dc00c000200010000000500070475737735c02dc00c00020001000000050008056173696131c02dc00c00020001000000050008056173696139c02dc00c00020001000000050008056e73312d31c02dc00c0002000100000005000a076e73312d313935c02dc02800010001000000050004c30a242ec04300010001000000050004451f1d39c05600010001000000050004451f3bc7c0690001000100000005000460073240c07c000100010000000500046007fb81c090000100010000000500047c283484c090001c00010000000500102a0226f0006700000000000000000064c0a400010001000000050004c16c5b01c0a4001c000100000005001026001401000200000000000000000001c0b800010001000000050004c16c5bc3c0b8001c0001000000050010260014010002000000000000000000c30000290500000000050000",
}
for i, hexData := range testMessages {
@ -298,7 +298,6 @@ func TestMsgLenTest2(t *testing.T) {
input, _ := hex.DecodeString(hexData)
m := new(Msg)
m.Unpack(input)
//println(m.String())
m.Compress = true
lenComp := m.Len()
b, _ := m.Pack()
@ -307,7 +306,6 @@ func TestMsgLenTest2(t *testing.T) {
lenUnComp := m.Len()
b, _ = m.Pack()
pacUnComp := len(b)
// TODO(miek): Len() gives back one more.
if pacComp != lenComp-1 {
t.Errorf("msg.Len(compressed)=%d actual=%d for test %d", lenComp, pacComp, i)
}

View File

@ -185,7 +185,7 @@ func (q *Question) String() (s string) {
}
func (q *Question) len() int {
l := len(q.Name) + 1
l := dLen(q.Name)
return l + 4
}
@ -207,7 +207,7 @@ type CNAME struct {
func (rr *CNAME) Header() *RR_Header { return &rr.Hdr }
func (rr *CNAME) copy() RR { return &CNAME{*rr.Hdr.copyHeader(), rr.Target} }
func (rr *CNAME) String() string { return rr.Hdr.String() + rr.Target }
func (rr *CNAME) len() int { return rr.Hdr.len() + len(rr.Target) + 1 }
func (rr *CNAME) len() int { return rr.Hdr.len() + dLen(rr.Target) }
type HINFO struct {
Hdr RR_Header
@ -229,7 +229,7 @@ func (rr *MB) Header() *RR_Header { return &rr.Hdr }
func (rr *MB) copy() RR { return &MB{*rr.Hdr.copyHeader(), rr.Mb} }
func (rr *MB) String() string { return rr.Hdr.String() + rr.Mb }
func (rr *MB) len() int { return rr.Hdr.len() + len(rr.Mb) + 1 }
func (rr *MB) len() int { return rr.Hdr.len() + dLen(rr.Mb) }
type MG struct {
Hdr RR_Header
@ -238,7 +238,7 @@ type MG struct {
func (rr *MG) Header() *RR_Header { return &rr.Hdr }
func (rr *MG) copy() RR { return &MG{*rr.Hdr.copyHeader(), rr.Mg} }
func (rr *MG) len() int { l := len(rr.Mg) + 1; return rr.Hdr.len() + l }
func (rr *MG) len() int { l := dLen(rr.Mg); return rr.Hdr.len() + l }
func (rr *MG) String() string { return rr.Hdr.String() + rr.Mg }
type MINFO struct {
@ -255,8 +255,8 @@ func (rr *MINFO) String() string {
}
func (rr *MINFO) len() int {
l := len(rr.Rmail) + 1
n := len(rr.Email) + 1
l := dLen(rr.Rmail)
n := dLen(rr.Email)
return rr.Hdr.len() + l + n
}
@ -267,7 +267,7 @@ type MR struct {
func (rr *MR) Header() *RR_Header { return &rr.Hdr }
func (rr *MR) copy() RR { return &MR{*rr.Hdr.copyHeader(), rr.Mr} }
func (rr *MR) len() int { l := len(rr.Mr) + 1; return rr.Hdr.len() + l }
func (rr *MR) len() int { l := dLen(rr.Mr); return rr.Hdr.len() + l }
func (rr *MR) String() string {
return rr.Hdr.String() + rr.Mr
@ -280,7 +280,7 @@ type MF struct {
func (rr *MF) Header() *RR_Header { return &rr.Hdr }
func (rr *MF) copy() RR { return &MF{*rr.Hdr.copyHeader(), rr.Mf} }
func (rr *MF) len() int { return rr.Hdr.len() + len(rr.Mf) + 1 }
func (rr *MF) len() int { return rr.Hdr.len() + dLen(rr.Mf) }
func (rr *MF) String() string {
return rr.Hdr.String() + " " + rr.Mf
@ -293,7 +293,7 @@ type MD struct {
func (rr *MD) Header() *RR_Header { return &rr.Hdr }
func (rr *MD) copy() RR { return &MD{*rr.Hdr.copyHeader(), rr.Md} }
func (rr *MD) len() int { return rr.Hdr.len() + len(rr.Md) + 1 }
func (rr *MD) len() int { return rr.Hdr.len() +dLen(rr.Md) }
func (rr *MD) String() string {
return rr.Hdr.String() + " " + rr.Md
@ -307,7 +307,7 @@ type MX struct {
func (rr *MX) Header() *RR_Header { return &rr.Hdr }
func (rr *MX) copy() RR { return &MX{*rr.Hdr.copyHeader(), rr.Preference, rr.Mx} }
func (rr *MX) len() int { l := len(rr.Mx) + 1; return rr.Hdr.len() + l + 2 }
func (rr *MX) len() int { l := dLen(rr.Mx); return rr.Hdr.len() + l + 2 }
func (rr *MX) String() string {
return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + rr.Mx
@ -321,7 +321,7 @@ type AFSDB struct {
func (rr *AFSDB) Header() *RR_Header { return &rr.Hdr }
func (rr *AFSDB) copy() RR { return &AFSDB{*rr.Hdr.copyHeader(), rr.Subtype, rr.Hostname} }
func (rr *AFSDB) len() int { l := len(rr.Hostname) + 1; return rr.Hdr.len() + l + 2 }
func (rr *AFSDB) len() int { l := dLen(rr.Hostname); return rr.Hdr.len() + l + 2 }
func (rr *AFSDB) String() string {
return rr.Hdr.String() + strconv.Itoa(int(rr.Subtype)) + " " + rr.Hostname
@ -348,7 +348,7 @@ type RT struct {
func (rr *RT) Header() *RR_Header { return &rr.Hdr }
func (rr *RT) copy() RR { return &RT{*rr.Hdr.copyHeader(), rr.Preference, rr.Host} }
func (rr *RT) len() int { l := len(rr.Host) + 1; return rr.Hdr.len() + l + 2 }
func (rr *RT) len() int { l := dLen(rr.Host); return rr.Hdr.len() + l + 2 }
func (rr *RT) String() string {
return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + rr.Host
@ -360,7 +360,7 @@ type NS struct {
}
func (rr *NS) Header() *RR_Header { return &rr.Hdr }
func (rr *NS) len() int { l := len(rr.Ns) + 1; return rr.Hdr.len() + l }
func (rr *NS) len() int { l := dLen(rr.Ns); return rr.Hdr.len() + l }
func (rr *NS) copy() RR { return &NS{*rr.Hdr.copyHeader(), rr.Ns} }
func (rr *NS) String() string {
@ -374,7 +374,7 @@ type PTR struct {
func (rr *PTR) Header() *RR_Header { return &rr.Hdr }
func (rr *PTR) copy() RR { return &PTR{*rr.Hdr.copyHeader(), rr.Ptr} }
func (rr *PTR) len() int { l := len(rr.Ptr) + 1; return rr.Hdr.len() + l }
func (rr *PTR) len() int { l := dLen(rr.Ptr); return rr.Hdr.len() + l }
func (rr *PTR) String() string {
return rr.Hdr.String() + rr.Ptr
@ -388,7 +388,7 @@ type RP struct {
func (rr *RP) Header() *RR_Header { return &rr.Hdr }
func (rr *RP) copy() RR { return &RP{*rr.Hdr.copyHeader(), rr.Mbox, rr.Txt} }
func (rr *RP) len() int { return rr.Hdr.len() + len(rr.Mbox) + 1 + len(rr.Txt) + 1 }
func (rr *RP) len() int { return rr.Hdr.len() + dLen(rr.Mbox) + dLen(rr.Txt) }
func (rr *RP) String() string {
return rr.Hdr.String() + rr.Mbox + " " + rr.Txt
@ -420,8 +420,8 @@ func (rr *SOA) String() string {
}
func (rr *SOA) len() int {
l := len(rr.Ns) + 1
n := len(rr.Mbox) + 1
l := dLen(rr.Ns)
n := dLen(rr.Mbox)
return rr.Hdr.len() + l + n + 20
}
@ -498,7 +498,7 @@ type SRV struct {
}
func (rr *SRV) Header() *RR_Header { return &rr.Hdr }
func (rr *SRV) len() int { l := len(rr.Target) + 1; return rr.Hdr.len() + l + 6 }
func (rr *SRV) len() int { l := dLen(rr.Target); return rr.Hdr.len() + l + 6 }
func (rr *SRV) copy() RR {
return &SRV{*rr.Hdr.copyHeader(), rr.Priority, rr.Weight, rr.Port, rr.Target}
}
@ -537,7 +537,7 @@ func (rr *NAPTR) String() string {
func (rr *NAPTR) len() int {
return rr.Hdr.len() + 4 + len(rr.Flags) + 1 + len(rr.Service) + 1 +
len(rr.Regexp) + 1 + len(rr.Replacement) + 1
len(rr.Regexp) + 1 + dLen(rr.Replacement)
}
// See RFC 4398.
@ -574,7 +574,7 @@ type DNAME struct {
func (rr *DNAME) Header() *RR_Header { return &rr.Hdr }
func (rr *DNAME) copy() RR { return &DNAME{*rr.Hdr.copyHeader(), rr.Target} }
func (rr *DNAME) len() int { l := len(rr.Target) + 1; return rr.Hdr.len() + l }
func (rr *DNAME) len() int { l := dLen(rr.Target); return rr.Hdr.len() + l }
func (rr *DNAME) String() string {
return rr.Hdr.String() + rr.Target
@ -624,7 +624,7 @@ func (rr *PX) copy() RR { return &PX{*rr.Hdr.copyHeader(), rr.Preferen
func (rr *PX) String() string {
return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + rr.Map822 + " " + rr.Mapx400
}
func (rr *PX) len() int { return rr.Hdr.len() + 2 + len(rr.Map822) + 1 + len(rr.Mapx400) + 1 }
func (rr *PX) len() int { return rr.Hdr.len() + 2 + dLen(rr.Map822) + dLen(rr.Mapx400) }
type GPOS struct {
Hdr RR_Header
@ -737,7 +737,7 @@ func (rr *RRSIG) String() string {
}
func (rr *RRSIG) len() int {
return rr.Hdr.len() + len(rr.SignerName) + 1 +
return rr.Hdr.len() + dLen(rr.SignerName) +
base64.StdEncoding.DecodedLen(len(rr.Signature)) + 18
}
@ -763,7 +763,7 @@ func (rr *NSEC) String() string {
}
func (rr *NSEC) len() int {
l := rr.Hdr.len() + len(rr.NextDomain) + 1
l := rr.Hdr.len() + dLen(rr.NextDomain)
lastwindow := uint32(2 ^ 32 + 1)
for _, t := range rr.TypeBitMap {
window := t / 256
@ -845,7 +845,7 @@ type KX struct {
}
func (rr *KX) Header() *RR_Header { return &rr.Hdr }
func (rr *KX) len() int { return rr.Hdr.len() + 2 + len(rr.Exchanger) + 1 }
func (rr *KX) len() int { return rr.Hdr.len() + 2 + dLen(rr.Exchanger) }
func (rr *KX) copy() RR { return &KX{*rr.Hdr.copyHeader(), rr.Preference, rr.Exchanger} }
func (rr *KX) String() string {
@ -882,7 +882,7 @@ type TALINK struct {
func (rr *TALINK) Header() *RR_Header { return &rr.Hdr }
func (rr *TALINK) copy() RR { return &TALINK{*rr.Hdr.copyHeader(), rr.PreviousName, rr.NextName} }
func (rr *TALINK) len() int { return rr.Hdr.len() + len(rr.PreviousName) + len(rr.NextName) + 2 }
func (rr *TALINK) len() int { return rr.Hdr.len() + dLen(rr.PreviousName) + dLen(rr.NextName) }
func (rr *TALINK) String() string {
return rr.Hdr.String() +
@ -998,7 +998,7 @@ type NSAPPTR struct {
func (rr *NSAPPTR) Header() *RR_Header { return &rr.Hdr }
func (rr *NSAPPTR) copy() RR { return &NSAPPTR{*rr.Hdr.copyHeader(), rr.Ptr} }
func (rr *NSAPPTR) String() string { return rr.Hdr.String() + rr.Ptr }
func (rr *NSAPPTR) len() int { return rr.Hdr.len() + len(rr.Ptr) }
func (rr *NSAPPTR) len() int { return rr.Hdr.len() + dLen(rr.Ptr) }
type NSEC3 struct {
Hdr RR_Header
@ -1093,7 +1093,7 @@ func (rr *TKEY) String() string {
}
func (rr *TKEY) len() int {
return rr.Hdr.len() + len(rr.Algorithm) + 1 + 4 + 4 + 6 +
return rr.Hdr.len() + dLen(rr.Algorithm) + 4 + 4 + 6 +
len(rr.Key) + 2 + len(rr.OtherData)
}
@ -1214,7 +1214,7 @@ func (rr *HIP) len() int {
len(rr.Hit)/2 +
base64.StdEncoding.DecodedLen(len(rr.PublicKey))
for _, d := range rr.RendezvousServers {
l += len(d) + 1
l += dLen(d)
}
return l
}
@ -1339,7 +1339,7 @@ type LP struct {
func (rr *LP) Header() *RR_Header { return &rr.Hdr }
func (rr *LP) copy() RR { return &LP{*rr.Hdr.copyHeader(), rr.Preference, rr.Fqdn} }
func (rr *LP) len() int { return rr.Hdr.len() + 2 + len(rr.Fqdn) + 1 }
func (rr *LP) len() int { return rr.Hdr.len() + 2 + dLen(rr.Fqdn) }
func (rr *LP) String() string {
return rr.Hdr.String() + strconv.Itoa(int(rr.Preference)) + " " + rr.Fqdn
@ -1509,6 +1509,17 @@ func copyIP(ip net.IP) net.IP {
return p
}
// dLen returns the length of a domain name. It returns 0 for the root zone.
// We are using the text here, but all other mechanisms allowed in the text
// representation of dname only make this name longer.
func dLen(s string) int {
if s == "." {
println("Called with root")
return 0
}
return len(s) + 1
}
// Map of constructors for each RR wire type.
var rr_mk = map[uint16]func() RR{
TypeA: func() RR { return new(A) },