diff --git a/command/server/listener_tcp.go b/command/server/listener_tcp.go index 9f0325064f..151069b7c6 100644 --- a/command/server/listener_tcp.go +++ b/command/server/listener_tcp.go @@ -3,6 +3,7 @@ package server import ( "fmt" "net" + "time" ) func tcpListenerFactory(config map[string]string) (net.Listener, error) { @@ -16,5 +17,26 @@ func tcpListenerFactory(config map[string]string) (net.Listener, error) { return nil, err } + ln = tcpKeepAliveListener{ln.(*net.TCPListener)} return listenerWrapTLS(ln, config) } + +// tcpKeepAliveListener sets TCP keep-alive timeouts on accepted +// connections. It's used by ListenAndServe and ListenAndServeTLS so +// dead TCP connections (e.g. closing laptop mid-download) eventually +// go away. +// +// This is copied directly from the Go source code. +type tcpKeepAliveListener struct { + *net.TCPListener +} + +func (ln tcpKeepAliveListener) Accept() (c net.Conn, err error) { + tc, err := ln.AcceptTCP() + if err != nil { + return + } + tc.SetKeepAlive(true) + tc.SetKeepAlivePeriod(3 * time.Minute) + return tc, nil +}