mirror of
https://github.com/shizunge/endlessh-go.git
synced 2026-06-23 04:10:08 +00:00
Merge pull request #196 from DarkWolfCave/fix/ghost-connections
Add TCP keepalive and write deadline on accepted connections
This commit is contained in:
@@ -54,6 +54,23 @@ func NewClient(conn net.Conn, interval time.Duration, maxClients int64) *Client
|
||||
time.Sleep(interval)
|
||||
}
|
||||
atomic.AddInt64(&numCurrentClients, 1)
|
||||
// Enable TCP keepalive to detect dead peers at the kernel level.
|
||||
// This is a safety net for long intervals where the write deadline
|
||||
// alone would be too slow to detect dead connections. For example,
|
||||
// with interval=10min, without keepalive a ghost connection would
|
||||
// go undetected for 10+ minutes.
|
||||
// Keepalive cannot detect peers that are alive at the TCP level
|
||||
// (kernel still responds to probes) but stalled at the application
|
||||
// level — the write deadline in Send() covers that case.
|
||||
// Detection time: ~idle + 9 probes (e.g. 10s + 9×10s ≈ 100s on Linux).
|
||||
if tcpConn, ok := conn.(*net.TCPConn); ok {
|
||||
tcpConn.SetKeepAlive(true)
|
||||
keepalive := interval
|
||||
if keepalive > 30*time.Second {
|
||||
keepalive = 30 * time.Second
|
||||
}
|
||||
tcpConn.SetKeepAlivePeriod(keepalive)
|
||||
}
|
||||
addr := conn.RemoteAddr().(*net.TCPAddr)
|
||||
glog.V(1).Infof("ACCEPT host=%v port=%v n=%v/%v\n", addr.IP, addr.Port, numCurrentClients, maxClients)
|
||||
return &Client{
|
||||
@@ -80,6 +97,10 @@ func (c *Client) Send(bannerMaxLength int64) (int, error) {
|
||||
}
|
||||
c.next = time.Now().Add(c.interval)
|
||||
length := rand.Int63n(bannerMaxLength)
|
||||
// Set a write deadline to detect dead connections where the kernel
|
||||
// buffers data but the remote peer is gone. Without this, Write()
|
||||
// can succeed indefinitely on dead connections, causing goroutine leaks.
|
||||
c.conn.SetWriteDeadline(time.Now().Add(c.interval))
|
||||
bytesSent, err := c.conn.Write(randStringBytes(length))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
|
||||
Reference in New Issue
Block a user