-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
update_test.go
152 lines (134 loc) · 4.37 KB
/
update_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package dns
import (
"bytes"
"testing"
)
func TestDynamicUpdateParsing(t *testing.T) {
const prefix = "example.com. IN "
for typ, name := range TypeToString {
switch typ {
case TypeNone, TypeReserved:
continue
case TypeANY:
// ANY is ambiguous here and ends up parsed as a CLASS.
//
// TODO(tmthrgd): Using TYPE255 here doesn't seem to work and also
// seems to fail for some other record types. Investigate.
continue
}
s := prefix + name
if _, err := NewRR(s); err != nil {
t.Errorf("failure to parse: %s: %v", s, err)
}
s += " \\# 0"
if _, err := NewRR(s); err != nil {
t.Errorf("failure to parse: %s: %v", s, err)
}
}
}
func TestDynamicUpdateUnpack(t *testing.T) {
// From https://github.com/miekg/dns/issues/150#issuecomment-62296803
// It should be an update message for the zone "example.",
// deleting the A RRset "example." and then adding an A record at "example.".
// class ANY, TYPE A
buf := []byte{171, 68, 40, 0, 0, 1, 0, 0, 0, 2, 0, 0, 7, 101, 120, 97, 109, 112, 108, 101, 0, 0, 6, 0, 1, 192, 12, 0, 1, 0, 255, 0, 0, 0, 0, 0, 0, 192, 12, 0, 1, 0, 1, 0, 0, 0, 0, 0, 4, 127, 0, 0, 1}
msg := new(Msg)
err := msg.Unpack(buf)
if err != nil {
t.Errorf("failed to unpack: %v\n%s", err, msg.String())
}
}
func TestDynamicUpdateZeroRdataUnpack(t *testing.T) {
m := new(Msg)
rr := &RR_Header{Name: ".", Rrtype: 0, Class: 1, Ttl: ^uint32(0), Rdlength: 0}
m.Answer = []RR{rr, rr, rr, rr, rr}
m.Ns = m.Answer
for n, s := range TypeToString {
rr.Rrtype = n
bytes, err := m.Pack()
if err != nil {
t.Errorf("failed to pack %s: %v", s, err)
continue
}
if err := new(Msg).Unpack(bytes); err != nil {
t.Errorf("failed to unpack %s: %v", s, err)
}
}
}
func TestRemoveRRset(t *testing.T) {
// Should add a zero data RR in Class ANY with a TTL of 0
// for each set mentioned in the RRs provided to it.
rr := testRR(". 100 IN A 127.0.0.1")
m := new(Msg)
m.Ns = []RR{&RR_Header{Name: ".", Rrtype: TypeA, Class: ClassANY, Ttl: 0, Rdlength: 0}}
expectstr := m.String()
expect, err := m.Pack()
if err != nil {
t.Fatalf("error packing expected msg: %v", err)
}
m.Ns = nil
m.RemoveRRset([]RR{rr})
actual, err := m.Pack()
if err != nil {
t.Fatalf("error packing actual msg: %v", err)
}
if !bytes.Equal(actual, expect) {
tmp := new(Msg)
if err := tmp.Unpack(actual); err != nil {
t.Fatalf("error unpacking actual msg: %v\nexpected: %v\ngot: %v\n", err, expect, actual)
}
t.Errorf("expected msg:\n%s", expectstr)
t.Errorf("actual msg:\n%v", tmp)
}
}
func TestPreReqAndRemovals(t *testing.T) {
// Build a list of multiple prereqs and then some removes followed by an insert.
// We should be able to add multiple prereqs and updates.
m := new(Msg)
m.SetUpdate("example.org.")
m.Id = 1234
// Use a full set of RRs each time, so we are sure the rdata is stripped.
rrName1 := testRR("name_used. 3600 IN A 127.0.0.1")
rrName2 := testRR("name_not_used. 3600 IN A 127.0.0.1")
rrRemove1 := testRR("remove1. 3600 IN A 127.0.0.1")
rrRemove2 := testRR("remove2. 3600 IN A 127.0.0.1")
rrRemove3 := testRR("remove3. 3600 IN A 127.0.0.1")
rrInsert := testRR("insert. 3600 IN A 127.0.0.1")
rrRrset1 := testRR("rrset_used1. 3600 IN A 127.0.0.1")
rrRrset2 := testRR("rrset_used2. 3600 IN A 127.0.0.1")
rrRrset3 := testRR("rrset_not_used. 3600 IN A 127.0.0.1")
// Handle the prereqs.
m.NameUsed([]RR{rrName1})
m.NameNotUsed([]RR{rrName2})
m.RRsetUsed([]RR{rrRrset1})
m.Used([]RR{rrRrset2})
m.RRsetNotUsed([]RR{rrRrset3})
// and now the updates.
m.RemoveName([]RR{rrRemove1})
m.RemoveRRset([]RR{rrRemove2})
m.Remove([]RR{rrRemove3})
m.Insert([]RR{rrInsert})
// This test function isn't a Example function because we print these RR with tabs at the
// end and the Example function trim these, thus they never match.
// TODO(miek): don't print these tabs and make this into an Example function.
expect := `;; opcode: UPDATE, status: NOERROR, id: 1234
;; flags:; ZONE: 1, PREREQ: 5, UPDATE: 4, ADDITIONAL: 0
;; ZONE SECTION:
;example.org. IN SOA
;; PREREQUISITE SECTION:
name_used. 0 CLASS255 ANY
name_not_used. 0 NONE ANY
rrset_used1. 0 CLASS255 A
rrset_used2. 0 IN A 127.0.0.1
rrset_not_used. 0 NONE A
;; UPDATE SECTION:
remove1. 0 CLASS255 ANY
remove2. 0 CLASS255 A
remove3. 0 NONE A 127.0.0.1
insert. 3600 IN A 127.0.0.1
`
if m.String() != expect {
t.Errorf("expected msg:\n%s", expect)
t.Errorf("actual msg:\n%v", m.String())
}
}