Skip to content

Commit 1a7e05e

Browse files
committed
net: add KeepAlive with default to ListenConfig
This commit adds a KeepAlive field to ListenConfig and uses it analogously to Dialer.KeepAlive to set TCP KeepAlives per default on Accept()
1 parent b0bcd7a commit 1a7e05e

File tree

5 files changed

+34
-24
lines changed

5 files changed

+34
-24
lines changed

src/net/dial.go

+8
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,14 @@ type ListenConfig struct {
596596
// necessarily the ones passed to Listen. For example, passing "tcp" to
597597
// Listen will cause the Control function to be called with "tcp4" or "tcp6".
598598
Control func(network, address string, c syscall.RawConn) error
599+
600+
// KeepAlive specifies the keep-alive period for network
601+
// connections accepted by this listener.
602+
// If zero, keep-alives are enabled if supported by the protocol
603+
// and operating system. Network protocols or operating systems
604+
// that do not support keep-alives ignore this field.
605+
// If negative, keep-alives are disabled.
606+
KeepAlive time.Duration
599607
}
600608

601609
// Listen announces on the local network address.

src/net/http/server.go

+2-20
Original file line numberDiff line numberDiff line change
@@ -2792,7 +2792,7 @@ func (srv *Server) ListenAndServe() error {
27922792
if err != nil {
27932793
return err
27942794
}
2795-
return srv.Serve(tcpKeepAliveListener{ln.(*net.TCPListener)})
2795+
return srv.Serve(ln)
27962796
}
27972797

27982798
var testHookServerServe func(*Server, net.Listener) // used if non-nil
@@ -3076,7 +3076,7 @@ func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error {
30763076

30773077
defer ln.Close()
30783078

3079-
return srv.ServeTLS(tcpKeepAliveListener{ln.(*net.TCPListener)}, certFile, keyFile)
3079+
return srv.ServeTLS(ln, certFile, keyFile)
30803080
}
30813081

30823082
// setupHTTP2_ServeTLS conditionally configures HTTP/2 on
@@ -3269,24 +3269,6 @@ func (tw *timeoutWriter) writeHeader(code int) {
32693269
tw.code = code
32703270
}
32713271

3272-
// tcpKeepAliveListener sets TCP keep-alive timeouts on accepted
3273-
// connections. It's used by ListenAndServe and ListenAndServeTLS so
3274-
// dead TCP connections (e.g. closing laptop mid-download) eventually
3275-
// go away.
3276-
type tcpKeepAliveListener struct {
3277-
*net.TCPListener
3278-
}
3279-
3280-
func (ln tcpKeepAliveListener) Accept() (net.Conn, error) {
3281-
tc, err := ln.AcceptTCP()
3282-
if err != nil {
3283-
return nil, err
3284-
}
3285-
tc.SetKeepAlive(true)
3286-
tc.SetKeepAlivePeriod(3 * time.Minute)
3287-
return tc, nil
3288-
}
3289-
32903272
// onceCloseListener wraps a net.Listener, protecting it from
32913273
// multiple Close calls.
32923274
type onceCloseListener struct {

src/net/tcpsock.go

+1
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ func DialTCP(network string, laddr, raddr *TCPAddr) (*TCPConn, error) {
224224
// use variables of type Listener instead of assuming TCP.
225225
type TCPListener struct {
226226
fd *netFD
227+
lc *ListenConfig
227228
}
228229

229230
// SyscallConn returns a raw network connection.

src/net/tcpsock_plan9.go

+11-2
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,16 @@ func (ln *TCPListener) accept() (*TCPConn, error) {
4444
if err != nil {
4545
return nil, err
4646
}
47-
return newTCPConn(fd), nil
47+
tc := newTCPConn(fd)
48+
if ln.lc.KeepAlive > -1 {
49+
setKeepAlive(fd, true)
50+
ka := d.KeepAlive
51+
if d.KeepAlive == 0 {
52+
ka = 3 * time.Minute
53+
}
54+
setKeepAlivePeriod(fd, ka)
55+
}
56+
return tc, nil
4857
}
4958

5059
func (ln *TCPListener) close() error {
@@ -74,5 +83,5 @@ func (sl *sysListener) listenTCP(ctx context.Context, laddr *TCPAddr) (*TCPListe
7483
if err != nil {
7584
return nil, err
7685
}
77-
return &TCPListener{fd}, nil
86+
return &TCPListener{fd: fd, lc: sl.ListenConfig}, nil
7887
}

src/net/tcpsock_posix.go

+12-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"io"
1212
"os"
1313
"syscall"
14+
"time"
1415
)
1516

1617
func sockaddrToTCP(sa syscall.Sockaddr) Addr {
@@ -140,7 +141,16 @@ func (ln *TCPListener) accept() (*TCPConn, error) {
140141
if err != nil {
141142
return nil, err
142143
}
143-
return newTCPConn(fd), nil
144+
tc := newTCPConn(fd)
145+
if ln.lc.KeepAlive > -1 {
146+
setKeepAlive(fd, true)
147+
ka := d.KeepAlive
148+
if d.KeepAlive == 0 {
149+
ka = 3 * time.Minute
150+
}
151+
setKeepAlivePeriod(fd, ka)
152+
}
153+
return tc, nil
144154
}
145155

146156
func (ln *TCPListener) close() error {
@@ -160,5 +170,5 @@ func (sl *sysListener) listenTCP(ctx context.Context, laddr *TCPAddr) (*TCPListe
160170
if err != nil {
161171
return nil, err
162172
}
163-
return &TCPListener{fd}, nil
173+
return &TCPListener{fd: fd, lc: sl.ListenConfig}, nil
164174
}

0 commit comments

Comments
 (0)