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