File: update_test.go

package info (click to toggle)
golang-github-miekg-dns 1.1.68-2
  • links: PTS, VCS
  • area: main
  • in suites: experimental, forky, sid
  • size: 1,260 kB
  • sloc: makefile: 3
file content (152 lines) | stat: -rw-r--r-- 4,477 bytes parent folder | download | duplicates (3)
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())
	}
}