summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2021-11-14 21:23:08 +0700
committerShulhan <ms@kilabit.info>2021-11-14 21:23:08 +0700
commit4e1e2f28af5af6639f035c3b903fb25b6e3e5807 (patch)
treece273aeecc6ff3beaa4ff656ea021fab70fb1f35
parentc2f3d1575ad29294ebadb9dd7ee6d7a06dc955ae (diff)
downloadpakakeh.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--.gitignore2
-rw-r--r--lib/dns/answer_test.go10
-rw-r--r--lib/dns/answers_test.go4
-rw-r--r--lib/dns/caches_test.go20
-rw-r--r--lib/dns/dns.go6
-rw-r--r--lib/dns/doh_client_test.go16
-rw-r--r--lib/dns/dot_client_test.go6
-rw-r--r--lib/dns/message.go8
-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.go76
-rw-r--r--lib/dns/message_header_test.go258
-rw-r--r--lib/dns/message_test.go44
-rw-r--r--lib/dns/tcp_client_test.go6
-rw-r--r--lib/dns/udp_client_example_test.go2
-rw-r--r--lib/dns/udp_client_test.go8
-rw-r--r--lib/dns/zone_file.go2
-rw-r--r--lib/dns/zone_file_test.go38
17 files changed, 463 insertions, 140 deletions
diff --git a/.gitignore b/.gitignore
index 69b1ab51..d3afe736 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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,