Closed michaelfortunato closed 7 months ago
Hello. Sorry for long reply. Yes, usually using flush in networking is unnecessary, but in your case it is necessary. Since it should work with any stream, please make a PR to become a contributor. Thank you
Is there any concern we are doing a syscall (the flush) on every invocation of process_handler? I assume in current usages of russh-sftp the buffer is being flushed on every request because most of them are using the channel struct from russh as their stream.
Is there any concern we are doing a syscall (the flush) on every invocation of process_handler? I assume in current usages of russh-sftp the buffer is being flushed on every request because most of them are using the channel struct from russh as their stream.
As I said above flush only has an effect on the file i/o. Flush implementation in the network make no sense, and function usually do not perform any useful overhead and return success (russh - call/implementation, tcpstream). In your case of working with file i/o, flush call is necessary because you need instant access to the data, so you have nothing to worry about
Fixed in PR #18
Question
Hi, I am currently writing an ssh daemon and trying to support the sftp subsystem. I noticed that
russh-sftp::server::process_handler
does not call flush each time it writes a response and was wondering if it should.Background - Spawning Handlers
What I have done is for each sftp sub-system request, I spawn a custom executable,
./sftp
which will handle the request onwards and my daemon communicates to it via its stdin and out. The daemon forwards the bytes from the socket to the sftp child proccess's stdin and forward the bytes from the child process's stdout to the socket (seeasync_io_copy_loop
). See the snippet hereBackground - Implementing The SFTP executable
In order to implement my
sftp
executable which will handle the connection, I wrote the following.As you can see I have created a new type
IOWrapper
which implementsAsyncRead
andAsyncWrite
and is just a small shim for tokio's stdin and stdout implementations.The Problem
The Problem is, when my sftp executable writes to stdout to respond to requests, the bytes are buffered so they do not actually get read by my ssh daemon. As a result, my ssh daemon in the
async_io_copy_loop
waits indefinitely for the child process's stdout to emit data, but it never does. I found that patchingrussh-sftp::server::process_handler
to flush on every write fixed the problem as the bytes were actually being written to stdout now.Misc - Update to
russh-sftp::server::process_handler
I added one line to
russh-sftp::server::process_handler
to do the flush on every write. I can make a pull request if this is a good implementation.Conclusion
Should we be flushing on write in process_handler or is my design, whereby I spawn a handler process for each client and forward bytes to its stdio, fundamentally flawed?
Thanks!