diff --git a/server.go b/server.go index af703046..41725222 100644 --- a/server.go +++ b/server.go @@ -304,17 +304,27 @@ func (srv *Server) ActivateAndServe() error { // ActivateAndServe will return. All in progress queries are completed before the server // is taken down. If the Shutdown was not succesful an error is returned. func (srv *Server) Shutdown() error { - // TODO(miek): does this work with socket activation? Double check if we set the - // address there. And... is it needed? - c := new(Client) - c.Net = srv.Net - switch srv.Net { + // Client sends fake request here to not wait for timeout in readUDP/readTCP loop + // and trap to stop event ASAP. + net, addr := srv.Net, srv.Addr + + if srv.Listener != nil { + a := srv.Listener.Addr() + net, addr = a.Network(), a.String() + } else if srv.PacketConn != nil { + a := srv.PacketConn.LocalAddr() + net, addr = a.Network(), a.String() + } + + switch net { case "tcp", "tcp4", "tcp6": go func() { srv.stopTCP <- true }() case "udp", "udp4", "udp6": go func() { srv.stopUDP <- true }() } - c.Exchange(new(Msg), srv.Addr) + c := &Client{Net: net} + c.Exchange(new(Msg), addr) + return nil } diff --git a/server_test.go b/server_test.go index ad86015c..bbea2f85 100644 --- a/server_test.go +++ b/server_test.go @@ -31,21 +31,33 @@ func AnotherHelloServer(w ResponseWriter, req *Msg) { w.WriteMsg(m) } +func RunLocalUDPServer() (*Server, string, error) { + pc, err := net.ListenPacket("udp", "127.0.0.1:0") + if err != nil { + return nil, "", err + } + server := &Server{PacketConn: pc} + go func() { + server.ActivateAndServe() + pc.Close() + }() + return server, pc.LocalAddr().String(), nil +} + func TestServing(t *testing.T) { HandleFunc("miek.nl.", HelloServer) HandleFunc("example.com.", AnotherHelloServer) - go func() { - err := ListenAndServe(":8053", "udp", nil) - if err != nil { - t.Log("ListenAndServe: ", err.Error()) - t.Fatal() - } - }() - time.Sleep(4e8) + + s, addrstr, err := RunLocalUDPServer() + if err != nil { + t.Fatalf("Unable to run test server on port 8053: %s", err) + } + defer s.Shutdown() + c := new(Client) m := new(Msg) m.SetQuestion("miek.nl.", TypeTXT) - r, _, err := c.Exchange(m, "127.0.0.1:8053") + r, _, err := c.Exchange(m, addrstr) if err != nil { t.Log("failed to exchange miek.nl", err) t.Fatal() @@ -57,7 +69,7 @@ func TestServing(t *testing.T) { } m.SetQuestion("example.com.", TypeTXT) - r, _, err = c.Exchange(m, "127.0.0.1:8053") + r, _, err = c.Exchange(m, addrstr) if err != nil { t.Log("failed to exchange example.com", err) t.Fatal() @@ -70,7 +82,7 @@ func TestServing(t *testing.T) { // Test Mixes cased as noticed by Ask. m.SetQuestion("eXaMplE.cOm.", TypeTXT) - r, _, err = c.Exchange(m, "127.0.0.1:8053") + r, _, err = c.Exchange(m, addrstr) if err != nil { t.Log("failed to exchange eXaMplE.cOm", err) t.Fail()