diff --git a/_examples/funkensturm/funkensturm.go b/_examples/funkensturm/funkensturm.go index 7da7b075..ab3515c3 100644 --- a/_examples/funkensturm/funkensturm.go +++ b/_examples/funkensturm/funkensturm.go @@ -223,7 +223,7 @@ func main() { s.Address = addr s.Port = port var srv *server - rs := make(chan bool) + rs := make(chan os.Error) go s.NewResponder(srv, rs) forever: @@ -236,7 +236,7 @@ forever: break forever } } - rs <- true // shutdown responder + rs <- nil // shutdown responder <-rs // wait for confirmation // And the resolvers for _, q := range qr { diff --git a/_examples/reflect/reflect.go b/_examples/reflect/reflect.go index c8fb237a..c41f3bfe 100644 --- a/_examples/reflect/reflect.go +++ b/_examples/reflect/reflect.go @@ -17,115 +17,118 @@ package main import ( + "os" "net" - "strconv" "dns" - "dns/responder" - "runtime" - "os/signal" + "strconv" + "dns/responder" + "runtime" + "os/signal" ) type server responder.Server func reply(a net.Addr, in []byte, tcp bool) *dns.Msg { - inmsg := new(dns.Msg) - if !inmsg.Unpack(in) { - println("Unpacking failed") - return nil - } - if inmsg.MsgHdr.Response == true { - return nil // Don't answer responses - } - m := new(dns.Msg) - m.MsgHdr.Id = inmsg.MsgHdr.Id - m.MsgHdr.Authoritative = true - m.MsgHdr.Response = true - m.MsgHdr.Opcode = dns.OpcodeQuery + inmsg := new(dns.Msg) + if !inmsg.Unpack(in) { + println("Unpacking failed") + return nil + } + if inmsg.MsgHdr.Response == true { + return nil // Don't answer responses + } + m := new(dns.Msg) + m.MsgHdr.Id = inmsg.MsgHdr.Id + m.MsgHdr.Authoritative = true + m.MsgHdr.Response = true + m.MsgHdr.Opcode = dns.OpcodeQuery - m.MsgHdr.Rcode = dns.RcodeSuccess - m.Question = make([]dns.Question, 1) - m.Answer = make([]dns.RR, 1) - m.Extra = make([]dns.RR, 1) + m.MsgHdr.Rcode = dns.RcodeSuccess + m.Question = make([]dns.Question, 1) + m.Answer = make([]dns.RR, 1) + m.Extra = make([]dns.RR, 1) - r := new(dns.RR_A) - r.Hdr = dns.RR_Header{Name: "whoami.miek.nl.", Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 0} - ip, _ := net.ResolveUDPAddr(a.String()) // No general variant for both upd and tcp - r.A = ip.IP.To4() // To4 very important + r := new(dns.RR_A) + r.Hdr = dns.RR_Header{Name: "whoami.miek.nl.", Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 0} + ip, _ := net.ResolveUDPAddr(a.String()) // No general variant for both upd and tcp + r.A = ip.IP.To4() // To4 very important - t := new(dns.RR_TXT) - t.Hdr = dns.RR_Header{Name: "whoami.miek.nl.", Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: 0} - if tcp { - t.Txt = "Port: " + strconv.Itoa(ip.Port) + " (tcp)" - } else { - t.Txt = "Port: " + strconv.Itoa(ip.Port) + " (udp)" - } + t := new(dns.RR_TXT) + t.Hdr = dns.RR_Header{Name: "whoami.miek.nl.", Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: 0} + if tcp { + t.Txt = "Port: " + strconv.Itoa(ip.Port) + " (tcp)" + } else { + t.Txt = "Port: " + strconv.Itoa(ip.Port) + " (udp)" + } - m.Question[0] = inmsg.Question[0] - m.Answer[0] = r - m.Extra[0] = t + m.Question[0] = inmsg.Question[0] + m.Answer[0] = r + m.Extra[0] = t - return m + return m } func (s *server) ResponderUDP(c *net.UDPConn, a net.Addr, in []byte) { - m := reply(a, in, false) - if m == nil { - return - } - out, ok := m.Pack() - if !ok { - println("Failed to pack") - return - } - responder.SendUDP(out, c, a) + m := reply(a, in, false) + if m == nil { + return + } + out, ok := m.Pack() + if !ok { + println("Failed to pack") + return + } + responder.SendUDP(out, c, a) } func (s *server) ResponderTCP(c *net.TCPConn, in []byte) { - m := reply(c.RemoteAddr(), in, true) - if m == nil { - return - } - out, ok := m.Pack() - if !ok { - println("Failed to pack") - return - } - responder.SendTCP(out, c) + m := reply(c.RemoteAddr(), in, true) + if m == nil { + return + } + out, ok := m.Pack() + if !ok { + println("Failed to pack") + return + } + responder.SendTCP(out, c) } func main() { - runtime.GOMAXPROCS(10) // Be bold + runtime.GOMAXPROCS(10) // Be bold - s := new(responder.Server) - s.Address = "127.0.0.1" - s.Port = "8053" - var srv *server - ch := make(chan bool) - go s.NewResponder(srv, ch) + s := new(responder.Server) + s.Address = "127.0.0.1" + s.Port = "8053" + var srv *server + ch := make(chan os.Error) + go s.NewResponder(srv, ch) - t := new(responder.Server) - t.Address = "127.0.0.1" - t.Port = "8053" - t.Tcp = true - var srvt *server - cht := make(chan bool) - go t.NewResponder(srvt, cht) + t := new(responder.Server) + t.Address = "127.0.0.1" + t.Port = "8053" + t.Tcp = true + var srvt *server + cht := make(chan os.Error) + go t.NewResponder(srvt, cht) forever: - for { - // Wait for a signal to stop - select { - case <-signal.Incoming: - println("Signal received, stopping") - ch <- true - cht <- true - break forever - case <-cht: - // last message from tcp channel - case <-ch: - // last message from udp channel - } - } - close(cht) - close(ch) + for { + // Wait for a signal to stop + select { + case <-signal.Incoming: + println("Signal received, stopping") + ch <- nil + cht <- nil + break forever + case e := <-cht: + // last message from tcp channel + println(e.String()) + case e := <-ch: + // last message from udp channel + println(e.String()) + } + } + close(cht) + close(ch) } diff --git a/_examples/rude/rude.go b/_examples/rude/rude.go index 0d441882..929c8e85 100644 --- a/_examples/rude/rude.go +++ b/_examples/rude/rude.go @@ -10,7 +10,8 @@ package main import ( - "net" + "os" + "net" "dns" "dns/responder" "os/signal" @@ -25,9 +26,9 @@ func (s *server) ResponderUDP(c *net.UDPConn, a net.Addr, in []byte) { // NXdomain 'n stuff println("Unpacking failed") } - if inmsg.MsgHdr.Response == true { - return // don't answer responses - } + if inmsg.MsgHdr.Response == true { + return // don't answer responses + } m := new(dns.Msg) m.MsgHdr.Id = inmsg.MsgHdr.Id m.MsgHdr.Response = true @@ -52,7 +53,7 @@ func main() { s.Address = "127.0.0.1" s.Port = "8053" var srv *server - ch := make(chan bool) + ch := make(chan os.Error) go s.NewResponder(srv, ch) forever: @@ -61,9 +62,13 @@ forever: select { case <-signal.Incoming: println("Signal received, stopping") - ch <- true - <-ch + ch <- nil + <-ch break forever + case e := <-cht: + println(e.String()) + case e := <-ch: + println(e.String()) } } } diff --git a/responder/responder.go b/responder/responder.go index 1286b113..fb6c10e3 100644 --- a/responder/responder.go +++ b/responder/responder.go @@ -59,12 +59,12 @@ type Responder interface { ResponderTCP(c *net.TCPConn, in []byte) } -// Start a new responder. The returned channel is only used to stop the responder. -// Send 'true' to make it stop -func (res *Server) NewResponder(h Responder, stop chan bool) { +// Start a new responder. The returned channel is used to stop the responder. +// Send 'nil' to make it stop. It can also return error via the channel. +func (res *Server) NewResponder(h Responder, stop chan os.Error) { var port string if len(res.Address) == 0 { - // We cannot start responding without an addresss + stop <- &dns.Error{Error: "No addresses"} return } if res.Port == "" { @@ -83,14 +83,12 @@ func (res *Server) NewResponder(h Responder, stop chan bool) { for { select { case <-stop: - stop <- true + stop <- nil listener.Close() break foreverTCP case s := <-tch: if s.err != nil { - // always fatal?? - stop <- false - println(s.err.String()) + stop <- s.err } else { go h.ResponderTCP(s.tcp, s.msg) } @@ -105,13 +103,11 @@ func (res *Server) NewResponder(h Responder, stop chan bool) { for { select { case <-stop: - stop <- true + stop <- nil break foreverUDP case s := <-uch: if s.err != nil { - //continue - stop <- false - println(s.err.String()) + stop <- s.err } else { go h.ResponderUDP(s.udp, s.addr, s.msg) } diff --git a/responder/responder_test.go b/responder/responder_test.go index 9897b644..449d9307 100644 --- a/responder/responder_test.go +++ b/responder/responder_test.go @@ -1,6 +1,7 @@ package responder import ( + "os" "testing" "fmt" "dns" @@ -66,7 +67,7 @@ func TestResponder(t *testing.T) { su.Address = "127.0.0.1" su.Port = "8053" var us *myserv - uch := make(chan bool) + uch := make(chan os.Error) go su.NewResponder(us, uch) /* tcp servertje */ @@ -75,23 +76,23 @@ func TestResponder(t *testing.T) { st.Port = "8053" st.Tcp = true var ts *myserv - tch := make(chan bool) + tch := make(chan os.Error) go st.NewResponder(ts, tch) time.Sleep(1 * 1e9) - uch <- true - tch <- true + uch <- nil + tch <- nil <-uch <-tch } /* func TestReflectorResponder(t *testing.T) { - stop := make(chan bool) + stop := make(chan os.Error) s := new(Server) s.Port = "8053" s.Address = "127.0.0.1" - stoptcp := make(chan bool) + stoptcp := make(chan os.Error) stcp := new(Server) stcp.Port = "8053" stcp.Address = "127.0.0.1" @@ -101,8 +102,8 @@ func TestReflectorResponder(t *testing.T) { go s.NewResponder(Reflector, stop) time.Sleep(1 * 1e9) - stop <- true - stoptcp <- true + stop <- nil + stoptcp <- nil <-stop <-stoptcp } @@ -175,7 +176,7 @@ func TestResponderTsig(t *testing.T) { su.Address = "127.0.0.1" su.Port = "8053" var us *servtsig - uch := make(chan bool) + uch := make(chan os.Error) go su.NewResponder(us, uch) /* tcp servertje */ @@ -184,11 +185,11 @@ func TestResponderTsig(t *testing.T) { st.Port = "8053" st.Tcp = true var ts *servtsig - tch := make(chan bool) + tch := make(chan os.Error) go st.NewResponder(ts, tch) time.Sleep(1 * 1e9) - uch <- true - tch <- true + uch <- nil + tch <- nil <-uch <-tch }