diff options
| author | Shulhan <ms@kilabit.info> | 2021-11-14 21:23:08 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2021-11-14 21:23:08 +0700 |
| commit | 4e1e2f28af5af6639f035c3b903fb25b6e3e5807 (patch) | |
| tree | ce273aeecc6ff3beaa4ff656ea021fab70fb1f35 | |
| parent | c2f3d1575ad29294ebadb9dd7ee6d7a06dc955ae (diff) | |
| download | pakakeh.go-4e1e2f28af5af6639f035c3b903fb25b6e3e5807.tar.xz | |
lib/dns: refactoring the section header
This changes rename the SectionHeader into MessageHeader.
The pack() method is optimized with the following results,
benchmark old ns/op new ns/op delta
BenchmarkMessageHeader_pack-8 66.2 21.7 -67.31%
benchmark old allocs new allocs delta
BenchmarkMessageHeader_pack-8 3 1 -66.67%
benchmark old bytes new bytes delta
BenchmarkMessageHeader_pack-8 32 16 -50.00%
The unpack() method is simplified by minimizing the if-condition.
This changes also fix the pack and unpack OpCode for value other then 0,
due to wrong shift value, 2 instead of 3.
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | lib/dns/answer_test.go | 10 | ||||
| -rw-r--r-- | lib/dns/answers_test.go | 4 | ||||
| -rw-r--r-- | lib/dns/caches_test.go | 20 | ||||
| -rw-r--r-- | lib/dns/dns.go | 6 | ||||
| -rw-r--r-- | lib/dns/doh_client_test.go | 16 | ||||
| -rw-r--r-- | lib/dns/dot_client_test.go | 6 | ||||
| -rw-r--r-- | lib/dns/message.go | 8 | ||||
| -rw-r--r-- | lib/dns/message_header.go (renamed from lib/dns/section_header.go) | 97 | ||||
| -rw-r--r-- | lib/dns/message_header_bench_test.go | 76 | ||||
| -rw-r--r-- | lib/dns/message_header_test.go | 258 | ||||
| -rw-r--r-- | lib/dns/message_test.go | 44 | ||||
| -rw-r--r-- | lib/dns/tcp_client_test.go | 6 | ||||
| -rw-r--r-- | lib/dns/udp_client_example_test.go | 2 | ||||
| -rw-r--r-- | lib/dns/udp_client_test.go | 8 | ||||
| -rw-r--r-- | lib/dns/zone_file.go | 2 | ||||
| -rw-r--r-- | lib/dns/zone_file_test.go | 38 |
17 files changed, 463 insertions, 140 deletions
@@ -1,3 +1,5 @@ +**/testdata/bench +**/testdata/pprof *.bak *.bench *.cprof diff --git a/lib/dns/answer_test.go b/lib/dns/answer_test.go index 6f95695c..1c083233 100644 --- a/lib/dns/answer_test.go +++ b/lib/dns/answer_test.go @@ -16,7 +16,7 @@ func TestNewAnswer(t *testing.T) { at := time.Now().Unix() msg1 := &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 1, }, Question: SectionQuestion{ @@ -120,7 +120,7 @@ func TestAnswerClear(t *testing.T) { func TestAnswerGet(t *testing.T) { // kilabit.info A res := &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 1, QDCount: 1, ANCount: 1, @@ -183,7 +183,7 @@ func TestAnswerGet(t *testing.T) { test.Assert(t, "ReceivedAt", an.ReceivedAt >= at-5, true) test.Assert(t, "AccessedAt", an.AccessedAt >= at, true) got := &Message{ - Header: SectionHeader{}, + Header: MessageHeader{}, Question: SectionQuestion{}, packet: gotPacket, } @@ -200,12 +200,12 @@ func TestAnswerGet(t *testing.T) { func TestAnswerUpdate(t *testing.T) { at := time.Now().Unix() - 5 msg1 := &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 1, }, } msg2 := &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 1, }, } diff --git a/lib/dns/answers_test.go b/lib/dns/answers_test.go index b17a305f..f3f758c3 100644 --- a/lib/dns/answers_test.go +++ b/lib/dns/answers_test.go @@ -159,7 +159,7 @@ func TestAnswersUpdate(t *testing.T) { RType: 1, RClass: 1, msg: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 1, }, }, @@ -178,7 +178,7 @@ func TestAnswersUpdate(t *testing.T) { RType: 1, RClass: 1, msg: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 2, }, }, diff --git a/lib/dns/caches_test.go b/lib/dns/caches_test.go index 17781d93..6d00a059 100644 --- a/lib/dns/caches_test.go +++ b/lib/dns/caches_test.go @@ -48,7 +48,7 @@ func TestCachesGet(t *testing.T) { RType: 1, RClass: 1, msg: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 1, }, }, @@ -59,7 +59,7 @@ func TestCachesGet(t *testing.T) { RType: 2, RClass: 1, msg: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 2, }, }, @@ -70,7 +70,7 @@ func TestCachesGet(t *testing.T) { RType: 3, RClass: 1, msg: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 3, }, }, @@ -126,7 +126,7 @@ func TestCachesPrune(t *testing.T) { RType: 1, RClass: 1, msg: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 1, }, }, @@ -138,7 +138,7 @@ func TestCachesPrune(t *testing.T) { RType: 2, RClass: 1, msg: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 2, }, }, @@ -150,7 +150,7 @@ func TestCachesPrune(t *testing.T) { RType: 3, RClass: 1, msg: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 3, }, }, @@ -195,7 +195,7 @@ func TestCachesUpsert(t *testing.T) { RType: 1, RClass: 1, msg: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 1, }, }, @@ -207,7 +207,7 @@ func TestCachesUpsert(t *testing.T) { RType: 1, RClass: 1, msg: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 3, }, }, @@ -219,7 +219,7 @@ func TestCachesUpsert(t *testing.T) { RType: 2, RClass: 1, msg: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 2, }, }, @@ -231,7 +231,7 @@ func TestCachesUpsert(t *testing.T) { RType: 2, RClass: 1, msg: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 4, }, }, diff --git a/lib/dns/dns.go b/lib/dns/dns.go index 8342933d..28a62d32 100644 --- a/lib/dns/dns.go +++ b/lib/dns/dns.go @@ -93,9 +93,9 @@ type OpCode byte // List of valid operation code. const ( - OpCodeQuery OpCode = iota // a standard query (QUERY) - OpCodeIQuery // an inverse query (IQUERY), obsolete by RFC3425 - OpCodeStatus // a server status request (STATUS) + OpCodeQuery OpCode = iota // A standard query (QUERY) + OpCodeIQuery // An inverse query (IQUERY), obsolete by RFC3425 + OpCodeStatus // A server status request (STATUS) ) // ResponseCode define response code in message header. diff --git a/lib/dns/doh_client_test.go b/lib/dns/doh_client_test.go index b8a3e2ab..3309a1ff 100644 --- a/lib/dns/doh_client_test.go +++ b/lib/dns/doh_client_test.go @@ -31,7 +31,7 @@ func TestDoHClient_Lookup(t *testing.T) { rclass: RecordClassIN, qname: "kilabit.info", exp: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 0, IsAA: true, QDCount: 1, @@ -59,7 +59,7 @@ func TestDoHClient_Lookup(t *testing.T) { rclass: RecordClassIN, qname: "kilabit.info", exp: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 0, IsAA: true, QDCount: 1, @@ -94,7 +94,7 @@ func TestDoHClient_Lookup(t *testing.T) { rclass: RecordClassIN, qname: "kilabit.info", exp: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 0, IsAA: true, QDCount: 1, @@ -121,7 +121,7 @@ func TestDoHClient_Lookup(t *testing.T) { rclass: RecordClassIN, qname: "kilabit.info", exp: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 0, IsAA: false, RCode: RCodeErrServer, @@ -176,7 +176,7 @@ func TestDoHClient_Post(t *testing.T) { rclass: RecordClassIN, qname: "kilabit.info", exp: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 0, IsAA: true, QDCount: 1, @@ -204,7 +204,7 @@ func TestDoHClient_Post(t *testing.T) { rclass: RecordClassIN, qname: "kilabit.info", exp: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 0, IsAA: true, QDCount: 1, @@ -239,7 +239,7 @@ func TestDoHClient_Post(t *testing.T) { rclass: RecordClassIN, qname: "kilabit.info", exp: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 0, IsAA: true, QDCount: 1, @@ -266,7 +266,7 @@ func TestDoHClient_Post(t *testing.T) { rclass: RecordClassIN, qname: "kilabit.info", exp: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 0, IsAA: false, RCode: RCodeErrServer, diff --git a/lib/dns/dot_client_test.go b/lib/dns/dot_client_test.go index 25701993..ee7c55fb 100644 --- a/lib/dns/dot_client_test.go +++ b/lib/dns/dot_client_test.go @@ -29,7 +29,7 @@ func TestDoTClient_Lookup(t *testing.T) { rclass: RecordClassIN, qname: "kilabit.info", exp: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 5, IsAA: true, QDCount: 1, @@ -57,7 +57,7 @@ func TestDoTClient_Lookup(t *testing.T) { rclass: RecordClassIN, qname: "kilabit.info", exp: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 6, IsAA: true, QDCount: 1, @@ -92,7 +92,7 @@ func TestDoTClient_Lookup(t *testing.T) { rclass: RecordClassIN, qname: "kilabit.info", exp: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 7, IsAA: true, QDCount: 1, diff --git a/lib/dns/message.go b/lib/dns/message.go index 8164f36b..0fa4532a 100644 --- a/lib/dns/message.go +++ b/lib/dns/message.go @@ -51,7 +51,7 @@ import ( // [1] RFC 1035 - 4.1. Format // type Message struct { - Header SectionHeader + Header MessageHeader Question SectionQuestion Answer []ResourceRecord Authority []ResourceRecord @@ -74,7 +74,7 @@ type Message struct { // func NewMessage() *Message { return &Message{ - Header: SectionHeader{ + Header: MessageHeader{ IsQuery: true, IsRD: true, QDCount: 1, @@ -120,7 +120,7 @@ func NewMessageAddress(hname []byte, addresses [][]byte) (msg *Message) { } msg = &Message{ - Header: SectionHeader{ + Header: MessageHeader{ IsAA: true, QDCount: 1, ANCount: 1, @@ -164,7 +164,7 @@ func NewMessageAddress(hname []byte, addresses [][]byte) (msg *Message) { // func NewMessageFromRR(rr *ResourceRecord) (msg *Message, err error) { msg = &Message{ - Header: SectionHeader{ + Header: MessageHeader{ IsAA: true, QDCount: 1, ANCount: 1, diff --git a/lib/dns/section_header.go b/lib/dns/message_header.go index 2844fcfb..a0d7d7bb 100644 --- a/lib/dns/section_header.go +++ b/lib/dns/message_header.go @@ -10,22 +10,25 @@ import ( const ( headerIsQuery byte = 0x00 - headerIsResponse byte = 0x80 - headerIsAA byte = 0x04 - headerIsTC byte = 0x02 - headerIsRD byte = 0x01 - headerIsRA byte = 0x80 + headerIsResponse byte = 0x80 // 1000.0000 + headerMaskOpCode byte = 0x78 // 0111.1000 + headerIsAA byte = 0x04 // 0000.0100 + headerIsTC byte = 0x02 // 0000.0010 + headerIsRD byte = 0x01 // 0000.0001 + headerIsRA byte = 0x80 // 1000.0000 + headerMaskRCode byte = 0x0F // 0000.1111 ) // -// SectionHeader The header section is always present. The header includes -// fields that specify which of the remaining sections are present, and also -// specify whether the message is a query or a response, a standard query or -// some other opcode, etc. [1] +// MessageHeader the header includes fields that specify which of the +// remaining sections are present, and also specify whether the message is a +// query or a response, a standard query or some other opcode, etc. [1] +// +// The header section is always present. // // [1] RFC 1035 P-25 - 4.1. Format // -type SectionHeader struct { +type MessageHeader struct { // // A 16 bit identifier assigned by the program that generates // any kind of query. This identifier is copied the corresponding @@ -82,27 +85,25 @@ type SectionHeader struct { // RCode ResponseCode - // An unsigned 16 bit integer specifying the number of entries in the - // question section. + // The number of entries in the question section. QDCount uint16 - // An unsigned 16 bit integer specifying the number of resource - // records in the answer section. + // The number of resource records in the answer section. ANCount uint16 - // An unsigned 16 bit integer specifying the number of name server - // resource records in the authority records section. + // The number of name server resource records in the authority records + // section. NSCount uint16 - // An unsigned 16 bit integer specifying the number of resource - // records in the additional records section. + // The number of resource records in the additional records section. ARCount uint16 } // -// Reset the header to default (query) values. +// Reset the header to default (query) values, which mean the IsQuery is true, +// the Op code is 0, with recursion enabled, and query count set tot 1. // -func (hdr *SectionHeader) Reset() { +func (hdr *MessageHeader) Reset() { hdr.ID = 0 hdr.IsQuery = true hdr.Op = OpCodeQuery @@ -111,7 +112,7 @@ func (hdr *SectionHeader) Reset() { hdr.IsRD = true hdr.IsRA = false hdr.RCode = RCodeOK - hdr.QDCount = 0 + hdr.QDCount = 1 hdr.ANCount = 0 hdr.NSCount = 0 hdr.ARCount = 0 @@ -120,10 +121,11 @@ func (hdr *SectionHeader) Reset() { // // pack the section header into slice of bytes. // -func (hdr *SectionHeader) pack() []byte { - var b0, b1 byte - - packet := make([]byte, 4) +func (hdr *MessageHeader) pack() []byte { + var ( + b0, b1 byte + packet [12]byte + ) packet[0] = byte(hdr.ID >> 8) packet[1] = byte(hdr.ID) @@ -134,7 +136,7 @@ func (hdr *SectionHeader) pack() []byte { b0 = headerIsResponse } - b0 |= (0x78 & byte(hdr.Op<<2)) + b0 |= (headerMaskOpCode & byte(hdr.Op<<3)) if hdr.IsRD { b0 |= headerIsRD @@ -150,48 +152,33 @@ func (hdr *SectionHeader) pack() []byte { if hdr.IsRA { b1 |= headerIsRA } - b1 |= (0x0F & byte(hdr.RCode)) + b1 |= (headerMaskRCode & byte(hdr.RCode)) } packet[2] = b0 packet[3] = b1 - packet = libbytes.AppendUint16(packet, hdr.QDCount) - packet = libbytes.AppendUint16(packet, hdr.ANCount) - packet = libbytes.AppendUint16(packet, hdr.NSCount) - packet = libbytes.AppendUint16(packet, hdr.ARCount) + libbytes.WriteUint16(packet[:], 4, hdr.QDCount) + libbytes.WriteUint16(packet[:], 6, hdr.ANCount) + libbytes.WriteUint16(packet[:], 8, hdr.NSCount) + libbytes.WriteUint16(packet[:], 10, hdr.ARCount) - return packet + return packet[:] } // // unpack the DNS header section. // -func (hdr *SectionHeader) unpack(packet []byte) { +func (hdr *MessageHeader) unpack(packet []byte) { hdr.ID = libbytes.ReadUint16(packet, 0) - if packet[2]&headerIsResponse == headerIsResponse { - hdr.IsQuery = false - } - hdr.Op = OpCode((packet[2] & 0x78) >> 2) - - if packet[2]&headerIsAA == headerIsAA { - hdr.IsAA = true - } - if packet[2]&headerIsTC == headerIsTC { - hdr.IsTC = true - } - if packet[2]&headerIsRD == headerIsRD { - hdr.IsRD = true - } else { - hdr.IsRD = false - } - - if packet[3]&headerIsRA == headerIsRA { - hdr.IsRA = true - } - - hdr.RCode = ResponseCode(0x0F & packet[3]) + hdr.IsQuery = packet[2]&headerIsResponse != headerIsResponse + hdr.Op = OpCode((packet[2] & headerMaskOpCode) >> 3) + hdr.IsAA = packet[2]&headerIsAA == headerIsAA + hdr.IsTC = packet[2]&headerIsTC == headerIsTC + hdr.IsRD = packet[2]&headerIsRD == headerIsRD + hdr.IsRA = packet[3]&headerIsRA == headerIsRA + hdr.RCode = ResponseCode(headerMaskRCode & packet[3]) hdr.QDCount = libbytes.ReadUint16(packet, 4) hdr.ANCount = libbytes.ReadUint16(packet, 6) diff --git a/lib/dns/message_header_bench_test.go b/lib/dns/message_header_bench_test.go new file mode 100644 index 00000000..16ce802e --- /dev/null +++ b/lib/dns/message_header_bench_test.go @@ -0,0 +1,76 @@ +// Copyright 2021, Shulhan <ms@kilabit.info>. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package dns + +import ( + "testing" +) + +/** + +Before 2021-11-14 + +$ go test -benchmem -bench=MessageHeader_pack -memprofile testdata/pprof/MessageHeader_unpack.mem.old > testdata/bench/MessageHeader_pack.old + +goos: linux +goarch: amd64 +pkg: github.com/shuLhan/share/lib/dns +cpu: 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz +BenchmarkMessageHeader_pack-8 19629273 66.25 ns/op 32 B/op 3 allocs/op + +After + +$ go test -benchmem -bench=MessageHeader_pack -memprofile testdata/pprof/MessageHeader_unpack.mem.new > testdata/bench/MessageHeader_pack.new + +goos: linux +goarch: amd64 +pkg: github.com/shuLhan/share/lib/dns +cpu: 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz +BenchmarkMessageHeader_pack-8 54183505 21.66 ns/op 16 B/op 1 allocs/op + +**/ +func BenchmarkMessageHeader_pack(b *testing.B) { + hdr := &MessageHeader{ + ID: 0xABCD, + Op: OpCodeQuery, + IsAA: true, + IsRD: true, + QDCount: 1, + ANCount: 4, + NSCount: 1, + ARCount: 1, + } + + for x := 0; x < b.N; x++ { + _ = hdr.pack() + } +} + +/** + +$ go test -benchmem -bench=MessageHeader_unpack -memprofile testdata/pprof/MessageHeader_unpack.mem.new > testdata/bench/MessageHeader_unpack.new + +goos: linux +goarch: amd64 +pkg: github.com/shuLhan/share/lib/dns +cpu: 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz +BenchmarkMessageHeader_unpack-8 310460067 3.848 ns/op 0 B/op 0 allocs/op + +**/ +func BenchmarkMessageHeader_unpack(b *testing.B) { + hdr := &MessageHeader{} + packet := []byte{ + 0xab, 0xcd, + 0x85, 0x00, + 0x00, 0x01, + 0x00, 0x04, + 0x00, 0x01, + 0x00, 0x01, + } + + for x := 0; x < b.N; x++ { + hdr.unpack(packet) + } +} diff --git a/lib/dns/message_header_test.go b/lib/dns/message_header_test.go new file mode 100644 index 00000000..c7c47315 --- /dev/null +++ b/lib/dns/message_header_test.go @@ -0,0 +1,258 @@ +// Copyright 2021, Shulhan <ms@kilabit.info>. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package dns + +import ( + "testing" + + "github.com/shuLhan/share/lib/test" +) + +type testMessageHeader struct { + desc string + hdr MessageHeader + packet []byte +} + +func testMessageHeaderCases() []testMessageHeader { + return []testMessageHeader{{ + desc: "As query", + hdr: MessageHeader{ + ID: 0xABCD, + IsQuery: true, + Op: OpCodeQuery, + QDCount: 1, + }, + packet: []byte{ + 0xab, 0xcd, + 0x00, 0x00, + 0x00, 0x01, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + }, + }, { + desc: "As inverse query", + hdr: MessageHeader{ + ID: 0xABCD, + IsQuery: true, + Op: OpCodeIQuery, + QDCount: 1, + }, + packet: []byte{ + 0xab, 0xcd, + 0x08, 0x00, + 0x00, 0x01, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + }, + }, { + desc: "As query server status", + hdr: MessageHeader{ + ID: 0xABCD, + IsQuery: true, + Op: OpCodeStatus, + }, + packet: []byte{ + 0xab, 0xcd, + 0x10, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + }, + }, { + desc: "As query, RD=1", + hdr: MessageHeader{ + ID: 0xABCD, + IsQuery: true, + Op: OpCodeQuery, + IsRD: true, + QDCount: 1, + }, + packet: []byte{ + 0xab, 0xcd, + 0x01, 0x00, + 0x00, 0x01, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + }, + }, { + desc: "As answer", + hdr: MessageHeader{ + ID: 0xABCD, + Op: OpCodeQuery, + QDCount: 1, + ANCount: 0x04, + }, + packet: []byte{ + 0xab, 0xcd, + 0x80, 0x00, + 0x00, 0x01, + 0x00, 0x04, + 0x00, 0x00, + 0x00, 0x00, + }, + }, { + desc: "As answer, RCode=5", + hdr: MessageHeader{ + ID: 0xABCD, + Op: OpCodeQuery, + RCode: RCodeRefused, + QDCount: 1, + }, + packet: []byte{ + 0xab, 0xcd, + 0x80, 0x05, + 0x00, 0x01, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + }, + }, { + desc: "As answer, IsAA=1", + hdr: MessageHeader{ + ID: 0xABCD, + Op: OpCodeQuery, + IsAA: true, + QDCount: 1, + }, + packet: []byte{ + 0xab, 0xcd, + 0x84, 0x00, + 0x00, 0x01, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + }, + }, { + desc: "As answer, IsTC=1", + hdr: MessageHeader{ + ID: 0xABCD, + Op: OpCodeQuery, + IsTC: true, + QDCount: 1, + }, + packet: []byte{ + 0xab, 0xcd, + 0x82, 0x00, + 0x00, 0x01, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + }, + }, { + desc: "As answer, IsRD=1", + hdr: MessageHeader{ + ID: 0xABCD, + Op: OpCodeQuery, + IsRD: true, + QDCount: 1, + }, + packet: []byte{ + 0xab, 0xcd, + 0x81, 0x00, + 0x00, 0x01, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + }, + }, { + desc: "As answer, IsTC=1 IsRD=1", + hdr: MessageHeader{ + ID: 0xABCD, + Op: OpCodeQuery, + IsTC: true, + IsRD: true, + QDCount: 1, + }, + packet: []byte{ + 0xab, 0xcd, + 0x83, 0x00, + 0x00, 0x01, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + }, + }, { + desc: "As answer, IsAA=1 IsRD=1", + hdr: MessageHeader{ + ID: 0xABCD, + Op: OpCodeQuery, + IsAA: true, + IsRD: true, + QDCount: 1, + ANCount: 3, + }, + packet: []byte{ + 0xab, 0xcd, + 0x85, 0x00, + 0x00, 0x01, + 0x00, 0x03, + 0x00, 0x00, + 0x00, 0x00, + }, + }, { + desc: "As answer, IsAA=1 IsTC=1 IsRD=1", + hdr: MessageHeader{ + ID: 0xABCD, + Op: OpCodeQuery, + IsAA: true, + IsTC: true, + IsRD: true, + QDCount: 1, + ANCount: 3, + }, + packet: []byte{ + 0xab, 0xcd, + 0x87, 0x00, + 0x00, 0x01, + 0x00, 0x03, + 0x00, 0x00, + 0x00, 0x00, + }, + }, { + desc: "As answer, IsAA=1 IsRD=1 all counts", + hdr: MessageHeader{ + ID: 0xABCD, + Op: OpCodeQuery, + IsAA: true, + IsRD: true, + QDCount: 1, + ANCount: 4, + NSCount: 1, + ARCount: 1, + }, + packet: []byte{ + 0xab, 0xcd, + 0x85, 0x00, + 0x00, 0x01, + 0x00, 0x04, + 0x00, 0x01, + 0x00, 0x01, + }, + }} +} + +func TestMessageHeader_pack(t *testing.T) { + cases := testMessageHeaderCases() + + for _, c := range cases { + got := c.hdr.pack() + test.Assert(t, c.desc, c.packet, got) + } +} + +func TestMessageHeader_unpack(t *testing.T) { + cases := testMessageHeaderCases() + + for _, c := range cases { + got := MessageHeader{} + got.unpack(c.packet) + test.Assert(t, c.desc, c.hdr, got) + } +} diff --git a/lib/dns/message_test.go b/lib/dns/message_test.go index 43647309..3b57d435 100644 --- a/lib/dns/message_test.go +++ b/lib/dns/message_test.go @@ -159,7 +159,7 @@ func TestMessagePack(t *testing.T) { }{{ desc: "Simple query", msg: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 1, IsQuery: true, QDCount: 1, @@ -187,7 +187,7 @@ func TestMessagePack(t *testing.T) { }, { desc: "Response with A RDATA", msg: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 0x8cdb, IsQuery: false, Op: OpCodeQuery, @@ -275,7 +275,7 @@ func TestMessagePack(t *testing.T) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, msg: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 0xd4a6, IsQuery: false, Op: OpCodeQuery, @@ -342,7 +342,7 @@ func TestMessagePack(t *testing.T) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, msg: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 0x8a38, IsQuery: false, Op: OpCodeQuery, @@ -389,7 +389,7 @@ func TestMessagePack(t *testing.T) { 0x51, 0x80, }, msg: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 2, IsQuery: false, Op: OpCodeQuery, @@ -473,7 +473,7 @@ func TestMessagePack(t *testing.T) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, msg: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 0x9eef, IsQuery: false, Op: OpCodeQuery, @@ -573,7 +573,7 @@ func TestMessagePack(t *testing.T) { 0x00, 0x00, 0x29, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, msg: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 16253, IsQuery: false, Op: OpCodeQuery, @@ -634,7 +634,7 @@ func TestMessagePack(t *testing.T) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, msg: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 0x2c90, IsRD: true, IsRA: true, @@ -732,7 +732,7 @@ func TestMessagePack(t *testing.T) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, msg: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 0x2cb4, IsRD: true, IsRA: true, @@ -837,7 +837,7 @@ func TestMessagePack(t *testing.T) { func TestMessageSetAuthoritativeAnswer(t *testing.T) { msgQuery := &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 1, IsQuery: true, IsAA: true, @@ -854,7 +854,7 @@ func TestMessageSetAuthoritativeAnswer(t *testing.T) { } msgResponse := &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 1, IsAA: true, IsRD: true, @@ -906,7 +906,7 @@ func TestMessageSetAuthoritativeAnswer(t *testing.T) { func TestMessageSetQuery(t *testing.T) { msgQuery := &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 1, IsQuery: true, IsAA: true, @@ -949,7 +949,7 @@ func TestMessageSetQuery(t *testing.T) { func TestMessageSetRecursionDesired(t *testing.T) { msgQuery := &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 1, IsQuery: true, IsAA: true, @@ -992,7 +992,7 @@ func TestMessageSetRecursionDesired(t *testing.T) { func TestMessageSetResponseCode(t *testing.T) { msgQuery := &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 1, IsQuery: true, IsAA: true, @@ -1059,7 +1059,7 @@ func TestMessageUnpack(t *testing.T) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, exp: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 0x8cdb, IsQuery: false, Op: OpCodeQuery, @@ -1131,7 +1131,7 @@ func TestMessageUnpack(t *testing.T) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, exp: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 0xd4a6, IsQuery: false, Op: OpCodeQuery, @@ -1210,7 +1210,7 @@ func TestMessageUnpack(t *testing.T) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, exp: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 0x8a38, IsQuery: false, Op: OpCodeQuery, @@ -1269,7 +1269,7 @@ func TestMessageUnpack(t *testing.T) { 0x00, 0x01, 0x51, 0x80, }, exp: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 2, IsQuery: false, Op: OpCodeQuery, @@ -1365,7 +1365,7 @@ func TestMessageUnpack(t *testing.T) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, exp: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 0x9eef, IsQuery: false, Op: OpCodeQuery, @@ -1512,7 +1512,7 @@ func TestMessageUnpack(t *testing.T) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, exp: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 16253, IsQuery: false, Op: OpCodeQuery, @@ -1604,7 +1604,7 @@ func TestMessageUnpack(t *testing.T) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, exp: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 0x2c90, IsRD: true, IsRA: true, @@ -1708,7 +1708,7 @@ func TestMessageUnpack(t *testing.T) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, exp: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 0x2cb4, IsRD: true, IsRA: true, diff --git a/lib/dns/tcp_client_test.go b/lib/dns/tcp_client_test.go index 6ab3d5f3..7726bfc3 100644 --- a/lib/dns/tcp_client_test.go +++ b/lib/dns/tcp_client_test.go @@ -29,7 +29,7 @@ func TestTCPClientLookup(t *testing.T) { rclass: RecordClassIN, qname: "kilabit.info", exp: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 5, IsAA: true, QDCount: 1, @@ -57,7 +57,7 @@ func TestTCPClientLookup(t *testing.T) { rclass: RecordClassIN, qname: "kilabit.info", exp: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 6, IsAA: true, QDCount: 1, @@ -92,7 +92,7 @@ func TestTCPClientLookup(t *testing.T) { rclass: RecordClassIN, qname: "kilabit.info", exp: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 7, IsAA: true, QDCount: 1, diff --git a/lib/dns/udp_client_example_test.go b/lib/dns/udp_client_example_test.go index 8fc2354b..0ccd9951 100644 --- a/lib/dns/udp_client_example_test.go +++ b/lib/dns/udp_client_example_test.go @@ -19,7 +19,7 @@ func ExampleUDPClient() { } req := &dns.Message{ - Header: dns.SectionHeader{}, + Header: dns.MessageHeader{}, Question: dns.SectionQuestion{ Name: "kilabit.info", Type: dns.RecordTypeA, diff --git a/lib/dns/udp_client_test.go b/lib/dns/udp_client_test.go index 4f81c1de..44489500 100644 --- a/lib/dns/udp_client_test.go +++ b/lib/dns/udp_client_test.go @@ -29,7 +29,7 @@ func TestUDPClientLookup(t *testing.T) { rclass: RecordClassIN, qname: "kilabit.info", exp: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 8, IsAA: true, QDCount: 1, @@ -57,7 +57,7 @@ func TestUDPClientLookup(t *testing.T) { rclass: RecordClassIN, qname: "kilabit.info", exp: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 9, IsAA: true, QDCount: 1, @@ -92,7 +92,7 @@ func TestUDPClientLookup(t *testing.T) { rclass: RecordClassIN, qname: "kilabit.info", exp: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 10, IsAA: true, QDCount: 1, @@ -119,7 +119,7 @@ func TestUDPClientLookup(t *testing.T) { rclass: RecordClassIN, qname: "kilabit.info", exp: &Message{ - Header: SectionHeader{ + Header: MessageHeader{ ID: 11, IsAA: false, RCode: RCodeErrServer, diff --git a/lib/dns/zone_file.go b/lib/dns/zone_file.go index 55adf329..896f9df9 100644 --- a/lib/dns/zone_file.go +++ b/lib/dns/zone_file.go @@ -161,7 +161,7 @@ func (zone *ZoneFile) Add(rr *ResourceRecord) (err error) { } msg := &Message{ - Header: SectionHeader{ + Header: MessageHeader{ IsAA: true, QDCount: 1, ANCount: 1, diff --git a/lib/dns/zone_file_test.go b/lib/dns/zone_file_test.go index 66381e50..c69b1fa2 100644 --- a/lib/dns/zone_file_test.go +++ b/lib/dns/zone_file_test.go @@ -164,7 +164,7 @@ VAXA A 10.2.0.27 `, exp: []*Message{{ - Header: SectionHeader{ + Header: MessageHeader{ IsAA: true, QDCount: 1, ANCount: 1, @@ -190,7 +190,7 @@ VAXA A 10.2.0.27 }, }}, }, { - Header: SectionHeader{ + Header: MessageHeader{ IsAA: true, QDCount: 1, ANCount: 3, @@ -220,7 +220,7 @@ VAXA A 10.2.0.27 Value: "vaxa.isi.edu", }}, }, { - Header: SectionHeader{ + Header: MessageHeader{ IsAA: true, QDCount: 1, ANCount: 2, @@ -250,7 +250,7 @@ VAXA A 10.2.0.27 }, }}, }, { - Header: SectionHeader{ + Header: MessageHeader{ IsAA: true, QDCount: 1, ANCount: 1, @@ -268,7 +268,7 @@ VAXA A 10.2.0.27 Value: "26.3.0.103", }}, }, { - Header: SectionHeader{ + Header: MessageHeader{ IsAA: true, QDCount: 1, ANCount: 2, @@ -292,7 +292,7 @@ VAXA A 10.2.0.27 Value: "128.9.0.32", }}, }, { - Header: SectionHeader{ + Header: MessageHeader{ IsAA: true, QDCount: 1, ANCount: 2, @@ -395,7 +395,7 @@ mail IN CNAME @ relay IN CNAME relay.pair.com. `, exp: []*Message{{ - Header: SectionHeader{ + Header: MessageHeader{ IsAA: true, QDCount: 1, ANCount: 1, @@ -421,7 +421,7 @@ relay IN CNAME relay.pair.com. }, }}, }, { - Header: SectionHeader{ + Header: MessageHeader{ IsAA: true, QDCount: 1, ANCount: 2, @@ -445,7 +445,7 @@ relay IN CNAME relay.pair.com. Value: "ns0.ns0.com", }}, }, { - Header: SectionHeader{ + Header: MessageHeader{ IsAA: true, QDCount: 1, ANCount: 1, @@ -463,7 +463,7 @@ relay IN CNAME relay.pair.com. Value: "127.0.0.1", }}, }, { - Header: SectionHeader{ + Header: MessageHeader{ IsAA: true, QDCount: 1, ANCount: 1, @@ -481,7 +481,7 @@ relay IN CNAME relay.pair.com. Value: "209.68.14.80", }}, }, { - Header: SectionHeader{ + Header: MessageHeader{ IsAA: true, QDCount: 1, ANCount: 1, @@ -502,7 +502,7 @@ relay IN CNAME relay.pair.com. }, }}, }, { - Header: SectionHeader{ + Header: MessageHeader{ IsAA: true, QDCount: 1, ANCount: 1, @@ -520,7 +520,7 @@ relay IN CNAME relay.pair.com. Value: "pcguide.com", }}, }, { - Header: SectionHeader{ + Header: MessageHeader{ IsAA: true, QDCount: 1, ANCount: 1, @@ -538,7 +538,7 @@ relay IN CNAME relay.pair.com. Value: "pcguide.com", }}, }, { - Header: SectionHeader{ + Header: MessageHeader{ IsAA: true, QDCount: 1, ANCount: 1, @@ -556,7 +556,7 @@ relay IN CNAME relay.pair.com. Value: "pcguide.com", }}, }, { - Header: SectionHeader{ + Header: MessageHeader{ IsAA: true, QDCount: 1, ANCount: 1, @@ -641,7 +641,7 @@ dev.kilabit.com. A 127.0.0.1 angularjs.doc A 127.0.0.1 `, exp: []*Message{{ - Header: SectionHeader{ + Header: MessageHeader{ IsAA: true, QDCount: 1, ANCount: 1, @@ -659,7 +659,7 @@ angularjs.doc A 127.0.0.1 Value: "127.0.0.1", }}, }, { - Header: SectionHeader{ + Header: MessageHeader{ IsAA: true, QDCount: 1, ANCount: 1, @@ -677,7 +677,7 @@ angularjs.doc A 127.0.0.1 Value: "127.0.0.1", }}, }, { - Header: SectionHeader{ + Header: MessageHeader{ IsAA: true, QDCount: 1, ANCount: 1, @@ -750,7 +750,7 @@ func TestZoneParseTXT(t *testing.T) { }{{ in: `@ IN TXT "This is a test"`, exp: []*Message{{ - Header: SectionHeader{ + Header: MessageHeader{ IsAA: true, QDCount: 1, ANCount: 1, |
