mscdex / mscdex/ssh2

[SFTP Server] Client hangs on exit

Open
#1,443 9 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
JavaScript
Stars
5.8k
Forks
734
PR merge metrics
No merged PRs in 30d

Description

I'm using a lightly modified version of the SFTP server example in the readme, along with the REALPATH logic from the SFTP example in the examples directory of this repo (found here). When I attempt to exit with this configuration, the server refuses to respond with an EOF after the client sends one.

Client logs:

What I see:

Connected to nmdebug.
debug2: Sending SSH2_FXP_REALPATH "."
debug3: Sent message fd 3 T:16 I:1
debug3: SSH2_FXP_REALPATH . -> /
sftp> exit
debug2: channel 0: read failed rfd 4 maxlen 32768: Broken pipe
debug2: channel 0: read failed
debug2: chan_shutdown_read: channel 0: (i0 o0 sock -1 wfd 4 efd 6 [write])
debug2: channel 0: input open -> drain
debug2: channel 0: ibuf empty
debug2: channel 0: send eof
debug3: send packet: type 96
debug2: channel 0: input drain -> closed

What I expect to see:

Connected to nmdebug.
debug2: Sending SSH2_FXP_REALPATH "."
debug3: Sent message fd 3 T:16 I:2
debug3: SSH2_FXP_REALPATH . -> /
sftp> exit
debug2: channel 0: read failed rfd 4 maxlen 32768: Broken pipe
debug2: channel 0: read failed
debug2: chan_shutdown_read: channel 0: (i0 o0 sock -1 wfd 4 efd 6 [write])
debug2: channel 0: input open -> drain
debug2: channel 0: ibuf empty
debug2: channel 0: send eof
debug3: send packet: type 96
debug2: channel 0: input drain -> closed
debug3: receive packet: type 96
debug2: channel 0: rcvd eof
debug2: channel 0: output open -> drain
debug2: channel 0: obuf empty
debug2: chan_shutdown_write: channel 0: (i3 o1 sock -1 wfd 5 efd 6 [write])
debug2: channel 0: output drain -> closed
debug3: receive packet: type 98
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
debug3: receive packet: type 97
debug2: channel 0: rcvd close
debug3: channel 0: will not send data after close
debug2: channel 0: almost dead
debug2: channel 0: gc: notify user
debug2: channel 0: gc: user detached
debug2: channel 0: send_close2
debug2: channel 0: send close for remote id 0
debug3: send packet: type 97
debug2: channel 0: is dead
debug2: channel 0: garbage collecting
debug1: channel 0: free: client-session, nchannels 1
debug3: channel 0: status: The following connections are open:
  #0 client-session (t4 [session] r0 nm0 i3/0 o3/0 e[write]/0 fd -1/-1/6 sock -1 cc -1 nc0 io 0x00/0x00)

debug3: send packet: type 1
Transferred: sent 4644, received 4684 bytes, in 5.2 seconds
Bytes per second: sent 887.8, received 895.4
debug1: Exit status 0

Server Logs:

Client authenticated!
[49892.626835718] Inbound: CHANNEL_OPEN (s:0, session)
[49892.626835718] Outbound: Sending CHANNEL_OPEN_CONFIRMATION (r:0, l:0)
[49892.626835718] Inbound: CHANNEL_REQUEST (r:0, subsystem: sftp)
Client SFTP session
[49892.626835718] Outbound: Sending CHANNEL_SUCCESS (r:0)
[49892.626835718] Inbound: CHANNEL_DATA (r:0, 9)
[49892.626835718] SFTP: Inbound: Received INIT (v3)
[49892.626835718] Outbound: Sending CHANNEL_DATA (r:0, 9)
[49892.626835718] Inbound: CHANNEL_DATA (r:0, 14)
[49892.626835718] SFTP: Inbound: Received REALPATH (id:1)
[49892.626835718] Outbound: Sending CHANNEL_DATA (r:0, 67)
[49892.626835718] SFTP: Outbound: Buffered NAME
[49892.626835718] Inbound: CHANNEL_EOF (r:0)

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the SFTP server example in the README and compare its REALPATH handling with examples/sftp-server-download-only.js, especially the linked REALPATH logic. Trace what happens after the server receives CHANNEL_EOF and buffers the NAME response. Done means the client receives the expected EOF, exit status, and close sequence instead of hanging.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, node.js
Domain
backend, networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.