@@ -213,16 +213,13 @@ func (p *SSHProxy) handleChannel(ctx context.Context, newChannel ssh.NewChannel,
213213 newChannel .Reject (ssh .ConnectionFailed , fmt .Sprintf ("failed to open channel: %v" , err ))
214214 return
215215 }
216- defer serverChannel .Close ()
217-
218216 // Accept the channel from client
219217 clientChannel , clientRequests , err := newChannel .Accept ()
220218 if err != nil {
221219 log .Error ().Err (err ).Str ("sessionID" , sessionID ).Msg ("Failed to accept client channel" )
222220 serverChannel .Close ()
223221 return
224222 }
225- defer clientChannel .Close ()
226223
227224 log .Info ().
228225 Str ("sessionID" , sessionID ).
@@ -232,9 +229,17 @@ func (p *SSHProxy) handleChannel(ctx context.Context, newChannel ssh.NewChannel,
232229 // Create per-channel state for tracking binary sessions (SFTP/SCP)
233230 chState := & channelState {}
234231
235- // Handle requests for this channel (pty-req, shell, exec, etc.)
236- go p .handleChannelRequests (clientRequests , serverChannel , sessionID , channelType , chState )
237- go p .handleChannelRequests (serverRequests , clientChannel , sessionID , channelType , chState )
232+ // Separate done channels to ensure exit-status is forwarded before channel teardown.
233+ serverReqDone := make (chan struct {})
234+ clientReqDone := make (chan struct {})
235+ go func () {
236+ defer close (clientReqDone )
237+ p .handleChannelRequests (clientRequests , serverChannel , sessionID , channelType , chState )
238+ }()
239+ go func () {
240+ defer close (serverReqDone )
241+ p .handleChannelRequests (serverRequests , clientChannel , sessionID , channelType , chState )
242+ }()
238243
239244 // Proxy data bidirectionally with logging
240245 errChan := make (chan error , 2 )
@@ -261,6 +266,12 @@ func (p *SSHProxy) handleChannel(ctx context.Context, newChannel ssh.NewChannel,
261266 log .Info ().Str ("sessionID" , sessionID ).Msg ("Channel cancelled by context" )
262267 }
263268
269+ // Let exit-status be forwarded before closing channels.
270+ <- serverReqDone
271+ clientChannel .Close ()
272+ serverChannel .Close ()
273+ <- clientReqDone
274+
264275 log .Debug ().
265276 Str ("sessionID" , sessionID ).
266277 Str ("channelType" , channelType ).
0 commit comments