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