adds tests for shutdown bind port (#400)

* adds tests for shutdown bind port

* closes file descriptors in for udp on linux

* adds sleep after shutdown in test

* minimizes defer usages

* reduces sleep time

* replaces sleep with notify channel

after starting DNS server
This commit is contained in:
Diep Pham 2016-12-15 23:20:35 +07:00 committed by Miek Gieben
parent 4744e915eb
commit 78bb99c423
2 changed files with 49 additions and 0 deletions

View File

@ -677,3 +677,43 @@ zDCJkckCgYEAndqM5KXGk5xYo+MAA1paZcbTUXwaWwjLU+XSRSSoyBEi5xMtfvUb
kFsxKCqxAnBVGEWAvVZAiiTOxleQFjz5RnL0BQp9Lg2cQe+dvuUmIAA=
-----END RSA PRIVATE KEY-----`)
)
func testShutdownBindPort(t *testing.T, protocol string, port string) {
handler := NewServeMux()
handler.HandleFunc(".", func(w ResponseWriter, r *Msg) {})
startedCh := make(chan struct{})
s := &Server{
Addr: net.JoinHostPort("127.0.0.1", port),
Net: protocol,
Handler: handler,
NotifyStartedFunc: func() {
startedCh <- struct{}{}
},
}
go func() {
if err := s.ListenAndServe(); err != nil {
t.Log(err)
}
}()
<-startedCh
t.Logf("DNS server is started on: %s", s.Addr)
if err := s.Shutdown(); err != nil {
t.Fatal(err)
}
time.Sleep(100 * time.Millisecond)
go func() {
if err := s.ListenAndServe(); err != nil {
t.Fatal(err)
}
}()
<-startedCh
t.Logf("DNS server is started on: %s", s.Addr)
}
func TestShutdownBindPortUDP(t *testing.T) {
testShutdownBindPort(t, "udp", "1153")
}
func TestShutdownBindPortTCP(t *testing.T) {
testShutdownBindPort(t, "tcp", "1154")
}

View File

@ -22,14 +22,17 @@ func setUDPSocketOptions4(conn *net.UDPConn) error {
return err
}
if err := syscall.SetsockoptInt(int(file.Fd()), syscall.IPPROTO_IP, syscall.IP_PKTINFO, 1); err != nil {
file.Close()
return err
}
// Calling File() above results in the connection becoming blocking, we must fix that.
// See https://github.com/miekg/dns/issues/279
err = syscall.SetNonblock(int(file.Fd()), true)
if err != nil {
file.Close()
return err
}
file.Close()
return nil
}
@ -40,12 +43,15 @@ func setUDPSocketOptions6(conn *net.UDPConn) error {
return err
}
if err := syscall.SetsockoptInt(int(file.Fd()), syscall.IPPROTO_IPV6, syscall.IPV6_RECVPKTINFO, 1); err != nil {
file.Close()
return err
}
err = syscall.SetNonblock(int(file.Fd()), true)
if err != nil {
file.Close()
return err
}
file.Close()
return nil
}
@ -59,8 +65,10 @@ func getUDPSocketOptions6Only(conn *net.UDPConn) (bool, error) {
// dual stack. See http://stackoverflow.com/questions/1618240/how-to-support-both-ipv4-and-ipv6-connections
v6only, err := syscall.GetsockoptInt(int(file.Fd()), syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY)
if err != nil {
file.Close()
return false, err
}
file.Close()
return v6only == 1, nil
}
@ -69,5 +77,6 @@ func getUDPSocketName(conn *net.UDPConn) (syscall.Sockaddr, error) {
if err != nil {
return nil, err
}
defer file.Close()
return syscall.Getsockname(int(file.Fd()))
}