fix: resolve copy goroutine deadlock on early connection close

- Add proper CloseWrite handling to signal EOF to other goroutine
- Ensure both copy goroutines terminate when either side closes
- Prevent goroutine leaks for SSH forwarded-tcpip channels:
    - Use select with default when sending result to resultChan
    - Close unused SSH channels and discard requests if main goroutine has already timed out
This commit is contained in:
2026-01-19 00:13:09 +07:00
parent 41fdb5639c
commit 8fb19af5a6
2 changed files with 40 additions and 18 deletions
+12 -1
View File
@@ -347,7 +347,18 @@ func forwardRequest(cw HTTPWriter, initialRequest RequestHeaderManager, sshSessi
go func() {
channel, reqs, err := sshSession.Lifecycle().Connection().OpenChannel("forwarded-tcpip", payload)
resultChan <- channelResult{channel, reqs, err}
select {
case resultChan <- channelResult{channel, reqs, err}:
default:
if channel != nil {
err := channel.Close()
if err != nil {
log.Printf("Failed to close unused channel: %v", err)
return
}
go ssh.DiscardRequests(reqs)
}
}
}()
var channel ssh.Channel