1package dns 2 3import ( 4 "net" 5 "sync" 6 "testing" 7 "time" 8) 9 10var ( 11 tsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="} 12 xfrSoa = testRR(`miek.nl. 0 IN SOA linode.atoom.net. miek.miek.nl. 2009032802 21600 7200 604800 3600`) 13 xfrA = testRR(`x.miek.nl. 1792 IN A 10.0.0.1`) 14 xfrMX = testRR(`miek.nl. 1800 IN MX 1 x.miek.nl.`) 15 xfrTestData = []RR{xfrSoa, xfrA, xfrMX, xfrSoa} 16) 17 18func InvalidXfrServer(w ResponseWriter, req *Msg) { 19 ch := make(chan *Envelope) 20 tr := new(Transfer) 21 22 go tr.Out(w, req, ch) 23 ch <- &Envelope{RR: []RR{}} 24 close(ch) 25 w.Hijack() 26} 27 28func SingleEnvelopeXfrServer(w ResponseWriter, req *Msg) { 29 ch := make(chan *Envelope) 30 tr := new(Transfer) 31 32 go tr.Out(w, req, ch) 33 ch <- &Envelope{RR: xfrTestData} 34 close(ch) 35 w.Hijack() 36} 37 38func MultipleEnvelopeXfrServer(w ResponseWriter, req *Msg) { 39 ch := make(chan *Envelope) 40 tr := new(Transfer) 41 42 go tr.Out(w, req, ch) 43 44 for _, rr := range xfrTestData { 45 ch <- &Envelope{RR: []RR{rr}} 46 } 47 close(ch) 48 w.Hijack() 49} 50 51func TestInvalidXfr(t *testing.T) { 52 HandleFunc("miek.nl.", InvalidXfrServer) 53 defer HandleRemove("miek.nl.") 54 55 s, addrstr, err := RunLocalTCPServer(":0") 56 if err != nil { 57 t.Fatalf("unable to run test server: %s", err) 58 } 59 defer s.Shutdown() 60 61 tr := new(Transfer) 62 m := new(Msg) 63 m.SetAxfr("miek.nl.") 64 65 c, err := tr.In(m, addrstr) 66 if err != nil { 67 t.Fatal("failed to zone transfer in", err) 68 } 69 70 for msg := range c { 71 if msg.Error == nil { 72 t.Fatal("failed to catch 'no SOA' error") 73 } 74 } 75} 76 77func TestSingleEnvelopeXfr(t *testing.T) { 78 HandleFunc("miek.nl.", SingleEnvelopeXfrServer) 79 defer HandleRemove("miek.nl.") 80 81 s, addrstr, err := RunLocalTCPServerWithTsig(":0", tsigSecret) 82 if err != nil { 83 t.Fatalf("unable to run test server: %s", err) 84 } 85 defer s.Shutdown() 86 87 axfrTestingSuite(addrstr) 88} 89 90func TestMultiEnvelopeXfr(t *testing.T) { 91 HandleFunc("miek.nl.", MultipleEnvelopeXfrServer) 92 defer HandleRemove("miek.nl.") 93 94 s, addrstr, err := RunLocalTCPServerWithTsig(":0", tsigSecret) 95 if err != nil { 96 t.Fatalf("unable to run test server: %s", err) 97 } 98 defer s.Shutdown() 99 100 axfrTestingSuite(addrstr) 101} 102 103func RunLocalTCPServerWithTsig(laddr string, tsig map[string]string) (*Server, string, error) { 104 server, l, _, err := RunLocalTCPServerWithFinChanWithTsig(laddr, tsig) 105 106 return server, l, err 107} 108 109func RunLocalTCPServerWithFinChanWithTsig(laddr string, tsig map[string]string) (*Server, string, chan error, error) { 110 l, err := net.Listen("tcp", laddr) 111 if err != nil { 112 return nil, "", nil, err 113 } 114 115 server := &Server{Listener: l, ReadTimeout: time.Hour, WriteTimeout: time.Hour, TsigSecret: tsig} 116 117 waitLock := sync.Mutex{} 118 waitLock.Lock() 119 server.NotifyStartedFunc = waitLock.Unlock 120 121 // See the comment in RunLocalUDPServerWithFinChan as to 122 // why fin must be buffered. 123 fin := make(chan error, 1) 124 125 go func() { 126 fin <- server.ActivateAndServe() 127 l.Close() 128 }() 129 130 waitLock.Lock() 131 return server, l.Addr().String(), fin, nil 132} 133 134func axfrTestingSuite(addrstr string) func(*testing.T) { 135 return func(t *testing.T) { 136 tr := new(Transfer) 137 m := new(Msg) 138 m.SetAxfr("miek.nl.") 139 140 c, err := tr.In(m, addrstr) 141 if err != nil { 142 t.Fatal("failed to zone transfer in", err) 143 } 144 145 var records []RR 146 for msg := range c { 147 if msg.Error != nil { 148 t.Fatal(msg.Error) 149 } 150 records = append(records, msg.RR...) 151 } 152 153 if len(records) != len(xfrTestData) { 154 t.Fatalf("bad axfr: expected %v, got %v", records, xfrTestData) 155 } 156 157 for i := range records { 158 if !IsDuplicate(records[i], xfrTestData[i]) { 159 t.Fatalf("bad axfr: expected %v, got %v", records, xfrTestData) 160 } 161 } 162 } 163} 164