dns/dns_test.go

317 lines
9.9 KiB
Go
Raw Normal View History

2011-07-04 18:21:01 +00:00
package dns
import (
"bytes"
"encoding/hex"
2012-01-11 20:03:47 +00:00
"net"
2011-07-04 18:21:01 +00:00
"testing"
)
func TestPackUnpack(t *testing.T) {
out := new(Msg)
out.Answer = make([]RR, 1)
Fix dominikh/go-tools nits (#758) * Remove unused functions and consts * Address gosimple nits * Address staticcheck nits This excludes several that were intentional or weren't actual errors. * Reduce size of lex struct This reduces the size of the lex struct by 8 bytes from: lex.token string: 0-16 (size 16, align 8) lex.tokenUpper string: 16-32 (size 16, align 8) lex.length int: 32-40 (size 8, align 8) lex.err bool: 40-41 (size 1, align 1) lex.value uint8: 41-42 (size 1, align 1) padding: 42-48 (size 6, align 0) lex.line int: 48-56 (size 8, align 8) lex.column int: 56-64 (size 8, align 8) lex.torc uint16: 64-66 (size 2, align 2) padding: 66-72 (size 6, align 0) lex.comment string: 72-88 (size 16, align 8) to: lex.token string: 0-16 (size 16, align 8) lex.tokenUpper string: 16-32 (size 16, align 8) lex.length int: 32-40 (size 8, align 8) lex.err bool: 40-41 (size 1, align 1) lex.value uint8: 41-42 (size 1, align 1) lex.torc uint16: 42-44 (size 2, align 2) padding: 44-48 (size 4, align 0) lex.line int: 48-56 (size 8, align 8) lex.column int: 56-64 (size 8, align 8) lex.comment string: 64-80 (size 16, align 8) * Reduce size of response struct This reduces the size of the response struct by 8 bytes from: response.msg []byte: 0-24 (size 24, align 8) response.hijacked bool: 24-25 (size 1, align 1) padding: 25-32 (size 7, align 0) response.tsigStatus error: 32-48 (size 16, align 8) response.tsigTimersOnly bool: 48-49 (size 1, align 1) padding: 49-56 (size 7, align 0) response.tsigRequestMAC string: 56-72 (size 16, align 8) response.tsigSecret map[string]string: 72-80 (size 8, align 8) response.udp *net.UDPConn: 80-88 (size 8, align 8) response.tcp net.Conn: 88-104 (size 16, align 8) response.udpSession *github.com/tmthrgd/dns.SessionUDP: 104-112 (size 8, align 8) response.writer github.com/tmthrgd/dns.Writer: 112-128 (size 16, align 8) response.wg *sync.WaitGroup: 128-136 (size 8, align 8) to: response.msg []byte: 0-24 (size 24, align 8) response.hijacked bool: 24-25 (size 1, align 1) response.tsigTimersOnly bool: 25-26 (size 1, align 1) padding: 26-32 (size 6, align 0) response.tsigStatus error: 32-48 (size 16, align 8) response.tsigRequestMAC string: 48-64 (size 16, align 8) response.tsigSecret map[string]string: 64-72 (size 8, align 8) response.udp *net.UDPConn: 72-80 (size 8, align 8) response.tcp net.Conn: 80-96 (size 16, align 8) response.udpSession *github.com/tmthrgd/dns.SessionUDP: 96-104 (size 8, align 8) response.writer github.com/tmthrgd/dns.Writer: 104-120 (size 16, align 8) response.wg *sync.WaitGroup: 120-128 (size 8, align 8)
2018-09-26 18:32:05 +00:00
key := &DNSKEY{Flags: 257, Protocol: 3, Algorithm: RSASHA1}
2011-08-08 13:12:24 +00:00
key.Hdr = RR_Header{Name: "miek.nl.", Rrtype: TypeDNSKEY, Class: ClassINET, Ttl: 3600}
2011-07-04 18:21:01 +00:00
key.PublicKey = "AwEAAaHIwpx3w4VHKi6i1LHnTaWeHCL154Jug0Rtc9ji5qwPXpBo6A5sRv7cSsPQKPIwxLpyCrbJ4mr2L0EPOdvP6z6YfljK2ZmTbogU9aSU2fiq/4wjxbdkLyoDVgtO+JsxNN4bjr4WcWhsmk1Hg93FV9ZpkWb0Tbad8DFqNDzr//kZ"
out.Answer[0] = key
2012-10-09 20:15:33 +00:00
msg, err := out.Pack()
if err != nil {
t.Error("failed to pack msg with DNSKEY")
2011-07-04 18:21:01 +00:00
}
in := new(Msg)
2012-10-09 20:15:33 +00:00
if in.Unpack(msg) != nil {
t.Error("failed to unpack msg with DNSKEY")
2011-07-04 18:21:01 +00:00
}
Fix dominikh/go-tools nits (#758) * Remove unused functions and consts * Address gosimple nits * Address staticcheck nits This excludes several that were intentional or weren't actual errors. * Reduce size of lex struct This reduces the size of the lex struct by 8 bytes from: lex.token string: 0-16 (size 16, align 8) lex.tokenUpper string: 16-32 (size 16, align 8) lex.length int: 32-40 (size 8, align 8) lex.err bool: 40-41 (size 1, align 1) lex.value uint8: 41-42 (size 1, align 1) padding: 42-48 (size 6, align 0) lex.line int: 48-56 (size 8, align 8) lex.column int: 56-64 (size 8, align 8) lex.torc uint16: 64-66 (size 2, align 2) padding: 66-72 (size 6, align 0) lex.comment string: 72-88 (size 16, align 8) to: lex.token string: 0-16 (size 16, align 8) lex.tokenUpper string: 16-32 (size 16, align 8) lex.length int: 32-40 (size 8, align 8) lex.err bool: 40-41 (size 1, align 1) lex.value uint8: 41-42 (size 1, align 1) lex.torc uint16: 42-44 (size 2, align 2) padding: 44-48 (size 4, align 0) lex.line int: 48-56 (size 8, align 8) lex.column int: 56-64 (size 8, align 8) lex.comment string: 64-80 (size 16, align 8) * Reduce size of response struct This reduces the size of the response struct by 8 bytes from: response.msg []byte: 0-24 (size 24, align 8) response.hijacked bool: 24-25 (size 1, align 1) padding: 25-32 (size 7, align 0) response.tsigStatus error: 32-48 (size 16, align 8) response.tsigTimersOnly bool: 48-49 (size 1, align 1) padding: 49-56 (size 7, align 0) response.tsigRequestMAC string: 56-72 (size 16, align 8) response.tsigSecret map[string]string: 72-80 (size 8, align 8) response.udp *net.UDPConn: 80-88 (size 8, align 8) response.tcp net.Conn: 88-104 (size 16, align 8) response.udpSession *github.com/tmthrgd/dns.SessionUDP: 104-112 (size 8, align 8) response.writer github.com/tmthrgd/dns.Writer: 112-128 (size 16, align 8) response.wg *sync.WaitGroup: 128-136 (size 8, align 8) to: response.msg []byte: 0-24 (size 24, align 8) response.hijacked bool: 24-25 (size 1, align 1) response.tsigTimersOnly bool: 25-26 (size 1, align 1) padding: 26-32 (size 6, align 0) response.tsigStatus error: 32-48 (size 16, align 8) response.tsigRequestMAC string: 48-64 (size 16, align 8) response.tsigSecret map[string]string: 64-72 (size 8, align 8) response.udp *net.UDPConn: 72-80 (size 8, align 8) response.tcp net.Conn: 80-96 (size 16, align 8) response.udpSession *github.com/tmthrgd/dns.SessionUDP: 96-104 (size 8, align 8) response.writer github.com/tmthrgd/dns.Writer: 104-120 (size 16, align 8) response.wg *sync.WaitGroup: 120-128 (size 8, align 8)
2018-09-26 18:32:05 +00:00
sig := &RRSIG{TypeCovered: TypeDNSKEY, Algorithm: RSASHA1, Labels: 2,
2011-07-04 18:21:01 +00:00
OrigTtl: 3600, Expiration: 4000, Inception: 4000, KeyTag: 34641, SignerName: "miek.nl.",
Signature: "AwEAAaHIwpx3w4VHKi6i1LHnTaWeHCL154Jug0Rtc9ji5qwPXpBo6A5sRv7cSsPQKPIwxLpyCrbJ4mr2L0EPOdvP6z6YfljK2ZmTbogU9aSU2fiq/4wjxbdkLyoDVgtO+JsxNN4bjr4WcWhsmk1Hg93FV9ZpkWb0Tbad8DFqNDzr//kZ"}
2011-08-08 13:12:24 +00:00
sig.Hdr = RR_Header{Name: "miek.nl.", Rrtype: TypeRRSIG, Class: ClassINET, Ttl: 3600}
2011-07-04 18:21:01 +00:00
out.Answer[0] = sig
2012-10-09 20:15:33 +00:00
msg, err = out.Pack()
if err != nil {
t.Error("failed to pack msg with RRSIG")
2011-07-04 18:21:01 +00:00
}
2012-10-09 20:15:33 +00:00
if in.Unpack(msg) != nil {
t.Error("failed to unpack msg with RRSIG")
2011-07-04 18:21:01 +00:00
}
}
2012-01-11 20:03:47 +00:00
func TestPackUnpack2(t *testing.T) {
m := new(Msg)
m.Extra = make([]RR, 1)
m.Answer = make([]RR, 1)
2012-01-12 22:17:34 +00:00
dom := "miek.nl."
rr := new(A)
2012-01-11 20:03:47 +00:00
rr.Hdr = RR_Header{Name: dom, Rrtype: TypeA, Class: ClassINET, Ttl: 0}
rr.A = net.IPv4(127, 0, 0, 1)
x := new(TXT)
2012-01-11 20:03:47 +00:00
x.Hdr = RR_Header{Name: dom, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}
x.Txt = []string{"heelalaollo"}
2012-01-11 20:03:47 +00:00
m.Extra[0] = x
m.Answer[0] = rr
2012-10-09 20:15:33 +00:00
_, err := m.Pack()
if err != nil {
t.Error("Packing failed: ", err)
2012-01-11 20:03:47 +00:00
return
}
}
2014-01-04 08:30:03 +00:00
func TestPackUnpack3(t *testing.T) {
m := new(Msg)
m.Extra = make([]RR, 2)
m.Answer = make([]RR, 1)
dom := "miek.nl."
rr := new(A)
rr.Hdr = RR_Header{Name: dom, Rrtype: TypeA, Class: ClassINET, Ttl: 0}
rr.A = net.IPv4(127, 0, 0, 1)
x1 := new(TXT)
x1.Hdr = RR_Header{Name: dom, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}
x1.Txt = []string{}
x2 := new(TXT)
x2.Hdr = RR_Header{Name: dom, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}
x2.Txt = []string{"heelalaollo"}
m.Extra[0] = x1
m.Extra[1] = x2
m.Answer[0] = rr
b, err := m.Pack()
if err != nil {
t.Error("packing failed: ", err)
2014-01-04 08:30:03 +00:00
return
}
var unpackMsg Msg
err = unpackMsg.Unpack(b)
if err != nil {
t.Error("unpacking failed")
2014-01-04 08:30:03 +00:00
return
}
}
2012-02-15 09:22:52 +00:00
func TestBailiwick(t *testing.T) {
2012-02-23 18:37:08 +00:00
yes := map[string]string{
"miek1.nl": "miek1.nl",
"miek.nl": "ns.miek.nl",
".": "miek.nl",
2012-02-23 18:37:08 +00:00
}
for parent, child := range yes {
if !IsSubDomain(parent, child) {
t.Errorf("%s should be child of %s", child, parent)
t.Errorf("comparelabels %d", CompareDomainName(parent, child))
t.Errorf("lenlabels %d %d", CountLabel(parent), CountLabel(child))
2012-02-23 18:37:08 +00:00
}
}
no := map[string]string{
2012-10-15 14:12:37 +00:00
"www.miek.nl": "ns.miek.nl",
"m\\.iek.nl": "ns.miek.nl",
"w\\.iek.nl": "w.iek.nl",
"p\\\\.iek.nl": "ns.p.iek.nl", // p\\.iek.nl , literal \ in domain name
"miek.nl": ".",
2012-02-23 18:37:08 +00:00
}
for parent, child := range no {
if IsSubDomain(parent, child) {
t.Errorf("%s should not be child of %s", child, parent)
t.Errorf("comparelabels %d", CompareDomainName(parent, child))
t.Errorf("lenlabels %d %d", CountLabel(parent), CountLabel(child))
2012-02-23 18:37:08 +00:00
}
}
2012-02-15 09:22:52 +00:00
}
2012-02-28 19:43:08 +00:00
func TestPackNAPTR(t *testing.T) {
for _, n := range []string{
`apple.com. IN NAPTR 100 50 "se" "SIP+D2U" "" _sip._udp.apple.com.`,
`apple.com. IN NAPTR 90 50 "se" "SIP+D2T" "" _sip._tcp.apple.com.`,
`apple.com. IN NAPTR 50 50 "se" "SIPS+D2T" "" _sips._tcp.apple.com.`,
} {
rr := testRR(n)
Properly calculate compressed message lengths (#833) * Remove fullSize return from compressionLenSearch This wasn't used anywhere but TestCompressionLenSearch, and was very wrong. * Add generated compressedLen functions and use them This replaces the confusing and complicated compressionLenSlice function. * Use compressedLenWithCompressionMap even for uncompressed This leaves the len() functions unused and they'll soon be removed. This also fixes the off-by-one error of compressedLen when a (Q)NAME is ".". * Use Len helper instead of RR.len private method * Merge len and compressedLen functions * Merge compressedLen helper into Msg.Len * Remove compress bool from compressedLenWithCompressionMap * Merge map insertion into compressionLenSearch This eliminates the need to loop over the domain name twice when we're compressing the name. * Use compressedNameLen for NSEC.NextDomain This was a mistake. * Remove compress from RR.len * Add test case for multiple questions length * Add test case for MINFO and SOA compression These are the only RRs with multiple compressible names within the same RR, and they were previously broken. * Rename compressedNameLen to domainNameLen It also handles the length of uncompressed domain names. * Use off directly instead of len(s[:off]) * Move initial maxCompressionOffset check out of compressionLenMapInsert This should allow us to avoid the call overhead of compressionLenMapInsert in certain limited cases and may result in a slight performance increase. compressionLenMapInsert still has a maxCompressionOffset check inside the for loop. * Rename compressedLenWithCompressionMap to msgLenWithCompressionMap This better reflects that it also calculates the uncompressed length. * Merge TestMsgCompressMINFO with TestMsgCompressSOA They're both testing the same thing. * Remove compressionLenMapInsert compressionLenSearch does everything compressionLenMapInsert did anyway. * Only call compressionLenSearch in one place in domainNameLen * Split if statement in domainNameLen The last two commits worsened the performance of domainNameLen noticably, this change restores it's original performance. name old time/op new time/op delta MsgLength-12 550ns ±13% 510ns ±21% ~ (p=0.050 n=10+10) MsgLengthNoCompression-12 26.9ns ± 2% 27.0ns ± 1% ~ (p=0.198 n=9+10) MsgLengthPack-12 2.30µs ±12% 2.26µs ±16% ~ (p=0.739 n=10+10) MsgLengthMassive-12 32.9µs ± 7% 32.0µs ±10% ~ (p=0.243 n=9+10) MsgLengthOnlyQuestion-12 9.60ns ± 1% 9.20ns ± 1% -4.16% (p=0.000 n=9+9) * Remove stray newline from TestMsgCompressionMultipleQuestions * Remove stray newline in length_test.go This was introduced when resolving merge conflicts.
2018-11-29 23:33:41 +00:00
msg := make([]byte, Len(rr))
if off, err := PackRR(rr, msg, 0, nil, false); err != nil {
t.Errorf("packing failed: %v", err)
Properly calculate compressed message lengths (#833) * Remove fullSize return from compressionLenSearch This wasn't used anywhere but TestCompressionLenSearch, and was very wrong. * Add generated compressedLen functions and use them This replaces the confusing and complicated compressionLenSlice function. * Use compressedLenWithCompressionMap even for uncompressed This leaves the len() functions unused and they'll soon be removed. This also fixes the off-by-one error of compressedLen when a (Q)NAME is ".". * Use Len helper instead of RR.len private method * Merge len and compressedLen functions * Merge compressedLen helper into Msg.Len * Remove compress bool from compressedLenWithCompressionMap * Merge map insertion into compressionLenSearch This eliminates the need to loop over the domain name twice when we're compressing the name. * Use compressedNameLen for NSEC.NextDomain This was a mistake. * Remove compress from RR.len * Add test case for multiple questions length * Add test case for MINFO and SOA compression These are the only RRs with multiple compressible names within the same RR, and they were previously broken. * Rename compressedNameLen to domainNameLen It also handles the length of uncompressed domain names. * Use off directly instead of len(s[:off]) * Move initial maxCompressionOffset check out of compressionLenMapInsert This should allow us to avoid the call overhead of compressionLenMapInsert in certain limited cases and may result in a slight performance increase. compressionLenMapInsert still has a maxCompressionOffset check inside the for loop. * Rename compressedLenWithCompressionMap to msgLenWithCompressionMap This better reflects that it also calculates the uncompressed length. * Merge TestMsgCompressMINFO with TestMsgCompressSOA They're both testing the same thing. * Remove compressionLenMapInsert compressionLenSearch does everything compressionLenMapInsert did anyway. * Only call compressionLenSearch in one place in domainNameLen * Split if statement in domainNameLen The last two commits worsened the performance of domainNameLen noticably, this change restores it's original performance. name old time/op new time/op delta MsgLength-12 550ns ±13% 510ns ±21% ~ (p=0.050 n=10+10) MsgLengthNoCompression-12 26.9ns ± 2% 27.0ns ± 1% ~ (p=0.198 n=9+10) MsgLengthPack-12 2.30µs ±12% 2.26µs ±16% ~ (p=0.739 n=10+10) MsgLengthMassive-12 32.9µs ± 7% 32.0µs ±10% ~ (p=0.243 n=9+10) MsgLengthOnlyQuestion-12 9.60ns ± 1% 9.20ns ± 1% -4.16% (p=0.000 n=9+9) * Remove stray newline from TestMsgCompressionMultipleQuestions * Remove stray newline in length_test.go This was introduced when resolving merge conflicts.
2018-11-29 23:33:41 +00:00
t.Errorf("length %d, need more than %d", Len(rr), off)
}
}
}
func TestToRFC3597(t *testing.T) {
a := testRR("miek.nl. IN A 10.0.1.1")
2013-02-08 15:47:21 +00:00
x := new(RFC3597)
x.ToRFC3597(a)
if x.String() != `miek.nl. 3600 CLASS1 TYPE1 \# 4 0a000101` {
t.Errorf("string mismatch, got: %s", x)
}
b := testRR("miek.nl. IN MX 10 mx.miek.nl.")
x.ToRFC3597(b)
if x.String() != `miek.nl. 3600 CLASS1 TYPE15 \# 14 000a026d78046d69656b026e6c00` {
t.Errorf("string mismatch, got: %s", x)
}
}
2013-08-26 04:38:10 +00:00
2013-08-27 04:24:06 +00:00
func TestNoRdataPack(t *testing.T) {
2013-08-26 04:38:10 +00:00
data := make([]byte, 1024)
2015-10-16 16:01:49 +00:00
for typ, fn := range TypeToRR {
r := fn()
*r.Header() = RR_Header{Name: "miek.nl.", Rrtype: typ, Class: ClassINET, Ttl: 16}
_, err := PackRR(r, data, 0, nil, false)
if err != nil {
t.Errorf("failed to pack RR with zero rdata: %s: %v", TypeToString[typ], err)
2013-08-26 04:38:10 +00:00
}
}
}
2013-08-27 04:24:06 +00:00
func TestNoRdataUnpack(t *testing.T) {
2013-08-27 04:24:06 +00:00
data := make([]byte, 1024)
2015-10-16 16:01:49 +00:00
for typ, fn := range TypeToRR {
if typ == TypeSOA || typ == TypeTSIG || typ == TypeTKEY {
2013-08-31 19:26:24 +00:00
// SOA, TSIG will not be seen (like this) in dyn. updates?
// TKEY requires length fields to be present for the Key and OtherData fields
continue
}
2013-08-27 04:24:06 +00:00
r := fn()
*r.Header() = RR_Header{Name: "miek.nl.", Rrtype: typ, Class: ClassINET, Ttl: 16}
off, err := PackRR(r, data, 0, nil, false)
if err != nil {
// Should always works, TestNoDataPack should have caught this
t.Errorf("failed to pack RR: %v", err)
2013-08-27 04:24:06 +00:00
continue
}
if _, _, err := UnpackRR(data[:off], 0); err != nil {
t.Errorf("failed to unpack RR with zero rdata: %s: %v", TypeToString[typ], err)
2013-08-27 04:24:06 +00:00
}
}
}
func TestRdataOverflow(t *testing.T) {
rr := new(RFC3597)
rr.Hdr.Name = "."
rr.Hdr.Class = ClassINET
rr.Hdr.Rrtype = 65280
rr.Rdata = hex.EncodeToString(make([]byte, 0xFFFF))
buf := make([]byte, 0xFFFF*2)
if _, err := PackRR(rr, buf, 0, nil, false); err != nil {
t.Fatalf("maximum size rrdata pack failed: %v", err)
}
rr.Rdata += "00"
if _, err := PackRR(rr, buf, 0, nil, false); err != ErrRdata {
t.Fatalf("oversize rrdata pack didn't return ErrRdata - instead: %v", err)
}
}
2014-06-06 20:10:38 +00:00
func TestCopy(t *testing.T) {
rr := testRR("miek.nl. 2311 IN A 127.0.0.1") // Weird TTL to avoid catching TTL
2014-06-06 20:10:38 +00:00
rr1 := Copy(rr)
if rr.String() != rr1.String() {
t.Fatalf("Copy() failed %s != %s", rr.String(), rr1.String())
}
}
func TestMsgCopy(t *testing.T) {
m := new(Msg)
m.SetQuestion("miek.nl.", TypeA)
rr := testRR("miek.nl. 2311 IN A 127.0.0.1")
m.Answer = []RR{rr}
rr = testRR("miek.nl. 2311 IN NS 127.0.0.1")
m.Ns = []RR{rr}
m1 := m.Copy()
if m.String() != m1.String() {
t.Fatalf("Msg.Copy() failed %s != %s", m.String(), m1.String())
}
m1.Answer[0] = testRR("somethingelse.nl. 2311 IN A 127.0.0.1")
if m.String() == m1.String() {
t.Fatalf("Msg.Copy() failed; change to copy changed template %s", m.String())
}
rr = testRR("miek.nl. 2311 IN A 127.0.0.2")
m1.Answer = append(m1.Answer, rr)
if m1.Ns[0].String() == m1.Answer[1].String() {
t.Fatalf("Msg.Copy() failed; append changed underlying array %s", m1.Ns[0].String())
}
}
func TestMsgPackBuffer(t *testing.T) {
var testMessages = []string{
// news.ycombinator.com.in.escapemg.com. IN A, response
"586285830001000000010000046e6577730b79636f6d62696e61746f7203636f6d02696e086573636170656d6703636f6d0000010001c0210006000100000e10002c036e7332c02103646e730b67726f6f7665736861726bc02d77ed50e600002a3000000e1000093a8000000e10",
// news.ycombinator.com.in.escapemg.com. IN A, question
"586201000001000000000000046e6577730b79636f6d62696e61746f7203636f6d02696e086573636170656d6703636f6d0000010001",
"398781020001000000000000046e6577730b79636f6d62696e61746f7203636f6d0000010001",
}
for i, hexData := range testMessages {
// we won't fail the decoding of the hex
input, _ := hex.DecodeString(hexData)
m := new(Msg)
if err := m.Unpack(input); err != nil {
t.Errorf("packet %d failed to unpack", i)
continue
}
}
}
// Make sure we can decode a TKEY packet from the string, modify the RR, and then pack it again.
func TestTKEY(t *testing.T) {
// An example TKEY RR captured. There is no known accepted standard text format for a TKEY
// record so we do this from a hex string instead of from a text readable string.
tkeyStr := "0737362d6d732d370932322d3332633233332463303439663961662d633065612d313165372d363839362d6463333937396666656666640000f900ff0000000000d2086773732d747369670059fd01f359fe53730003000000b8a181b53081b2a0030a0100a10b06092a864882f712010202a2819d04819a60819706092a864886f71201020202006f8187308184a003020105a10302010fa2783076a003020112a26f046db29b1b1d2625da3b20b49dafef930dd1e9aad335e1c5f45dcd95e0005d67a1100f3e573d70506659dbed064553f1ab890f68f65ae10def0dad5b423b39f240ebe666f2886c5fe03819692d29182bbed87b83e1f9d16b7334ec16a3c4fc5ad4a990088e0be43f0c6957916f5fe60000"
tkeyBytes, err := hex.DecodeString(tkeyStr)
if err != nil {
t.Fatal("unable to decode TKEY string ", err)
}
// Decode the RR
rr, tkeyLen, unPackErr := UnpackRR(tkeyBytes, 0)
if unPackErr != nil {
t.Fatal("unable to decode TKEY RR", unPackErr)
}
// Make sure it's a TKEY record
if rr.Header().Rrtype != TypeTKEY {
t.Fatal("Unable to decode TKEY")
}
// Make sure we get back the same length
Properly calculate compressed message lengths (#833) * Remove fullSize return from compressionLenSearch This wasn't used anywhere but TestCompressionLenSearch, and was very wrong. * Add generated compressedLen functions and use them This replaces the confusing and complicated compressionLenSlice function. * Use compressedLenWithCompressionMap even for uncompressed This leaves the len() functions unused and they'll soon be removed. This also fixes the off-by-one error of compressedLen when a (Q)NAME is ".". * Use Len helper instead of RR.len private method * Merge len and compressedLen functions * Merge compressedLen helper into Msg.Len * Remove compress bool from compressedLenWithCompressionMap * Merge map insertion into compressionLenSearch This eliminates the need to loop over the domain name twice when we're compressing the name. * Use compressedNameLen for NSEC.NextDomain This was a mistake. * Remove compress from RR.len * Add test case for multiple questions length * Add test case for MINFO and SOA compression These are the only RRs with multiple compressible names within the same RR, and they were previously broken. * Rename compressedNameLen to domainNameLen It also handles the length of uncompressed domain names. * Use off directly instead of len(s[:off]) * Move initial maxCompressionOffset check out of compressionLenMapInsert This should allow us to avoid the call overhead of compressionLenMapInsert in certain limited cases and may result in a slight performance increase. compressionLenMapInsert still has a maxCompressionOffset check inside the for loop. * Rename compressedLenWithCompressionMap to msgLenWithCompressionMap This better reflects that it also calculates the uncompressed length. * Merge TestMsgCompressMINFO with TestMsgCompressSOA They're both testing the same thing. * Remove compressionLenMapInsert compressionLenSearch does everything compressionLenMapInsert did anyway. * Only call compressionLenSearch in one place in domainNameLen * Split if statement in domainNameLen The last two commits worsened the performance of domainNameLen noticably, this change restores it's original performance. name old time/op new time/op delta MsgLength-12 550ns ±13% 510ns ±21% ~ (p=0.050 n=10+10) MsgLengthNoCompression-12 26.9ns ± 2% 27.0ns ± 1% ~ (p=0.198 n=9+10) MsgLengthPack-12 2.30µs ±12% 2.26µs ±16% ~ (p=0.739 n=10+10) MsgLengthMassive-12 32.9µs ± 7% 32.0µs ±10% ~ (p=0.243 n=9+10) MsgLengthOnlyQuestion-12 9.60ns ± 1% 9.20ns ± 1% -4.16% (p=0.000 n=9+9) * Remove stray newline from TestMsgCompressionMultipleQuestions * Remove stray newline in length_test.go This was introduced when resolving merge conflicts.
2018-11-29 23:33:41 +00:00
if Len(rr) != len(tkeyBytes) {
t.Fatalf("Lengths don't match %d != %d", Len(rr), len(tkeyBytes))
}
// make space for it with some fudge room
msg := make([]byte, tkeyLen+1000)
offset, packErr := PackRR(rr, msg, 0, nil, false)
if packErr != nil {
t.Fatal("unable to pack TKEY RR", packErr)
}
if offset != len(tkeyBytes) {
t.Fatalf("mismatched TKEY RR size %d != %d", len(tkeyBytes), offset)
}
Fix dominikh/go-tools nits (#758) * Remove unused functions and consts * Address gosimple nits * Address staticcheck nits This excludes several that were intentional or weren't actual errors. * Reduce size of lex struct This reduces the size of the lex struct by 8 bytes from: lex.token string: 0-16 (size 16, align 8) lex.tokenUpper string: 16-32 (size 16, align 8) lex.length int: 32-40 (size 8, align 8) lex.err bool: 40-41 (size 1, align 1) lex.value uint8: 41-42 (size 1, align 1) padding: 42-48 (size 6, align 0) lex.line int: 48-56 (size 8, align 8) lex.column int: 56-64 (size 8, align 8) lex.torc uint16: 64-66 (size 2, align 2) padding: 66-72 (size 6, align 0) lex.comment string: 72-88 (size 16, align 8) to: lex.token string: 0-16 (size 16, align 8) lex.tokenUpper string: 16-32 (size 16, align 8) lex.length int: 32-40 (size 8, align 8) lex.err bool: 40-41 (size 1, align 1) lex.value uint8: 41-42 (size 1, align 1) lex.torc uint16: 42-44 (size 2, align 2) padding: 44-48 (size 4, align 0) lex.line int: 48-56 (size 8, align 8) lex.column int: 56-64 (size 8, align 8) lex.comment string: 64-80 (size 16, align 8) * Reduce size of response struct This reduces the size of the response struct by 8 bytes from: response.msg []byte: 0-24 (size 24, align 8) response.hijacked bool: 24-25 (size 1, align 1) padding: 25-32 (size 7, align 0) response.tsigStatus error: 32-48 (size 16, align 8) response.tsigTimersOnly bool: 48-49 (size 1, align 1) padding: 49-56 (size 7, align 0) response.tsigRequestMAC string: 56-72 (size 16, align 8) response.tsigSecret map[string]string: 72-80 (size 8, align 8) response.udp *net.UDPConn: 80-88 (size 8, align 8) response.tcp net.Conn: 88-104 (size 16, align 8) response.udpSession *github.com/tmthrgd/dns.SessionUDP: 104-112 (size 8, align 8) response.writer github.com/tmthrgd/dns.Writer: 112-128 (size 16, align 8) response.wg *sync.WaitGroup: 128-136 (size 8, align 8) to: response.msg []byte: 0-24 (size 24, align 8) response.hijacked bool: 24-25 (size 1, align 1) response.tsigTimersOnly bool: 25-26 (size 1, align 1) padding: 26-32 (size 6, align 0) response.tsigStatus error: 32-48 (size 16, align 8) response.tsigRequestMAC string: 48-64 (size 16, align 8) response.tsigSecret map[string]string: 64-72 (size 8, align 8) response.udp *net.UDPConn: 72-80 (size 8, align 8) response.tcp net.Conn: 80-96 (size 16, align 8) response.udpSession *github.com/tmthrgd/dns.SessionUDP: 96-104 (size 8, align 8) response.writer github.com/tmthrgd/dns.Writer: 104-120 (size 16, align 8) response.wg *sync.WaitGroup: 120-128 (size 8, align 8)
2018-09-26 18:32:05 +00:00
if !bytes.Equal(tkeyBytes, msg[0:offset]) {
t.Fatal("mismatched TKEY data after rewriting bytes")
}
// Now add some bytes to this and make sure we can encode OtherData properly
tkey := rr.(*TKEY)
tkey.OtherData = "abcd"
tkey.OtherLen = 2
offset, packErr = PackRR(tkey, msg, 0, nil, false)
if packErr != nil {
t.Fatal("unable to pack TKEY RR after modification", packErr)
}
if offset != len(tkeyBytes)+2 {
t.Fatalf("mismatched TKEY RR size %d != %d", offset, len(tkeyBytes)+2)
}
// Make sure we can parse our string output
tkey.Hdr.Class = ClassINET // https://github.com/miekg/dns/issues/577
_, newError := NewRR(tkey.String())
if newError != nil {
t.Fatalf("unable to parse TKEY string: %s", newError)
}
}