SSH Window flow control operation in OpenSSH.
tom at quarendon.net
tom at quarendon.net
Mon Mar 13 06:35:16 AEDT 2017
Apologies if this is not an appropriate question for this list, but I'm hoping to find some experts who might be able to give me a general answer to how this operates in openSSH (or SSH daemons generally).
I'm fairly familiar with the SSH connection protocol spec and the concept of the window and the SSH_MSG_CHANNEL_WINDOW_ADJUST message in order to implement channel flow control.
What I can't figure out, and I haven't really been able to glean from the OpenSSH source so far is how one (openSSH) actually makes use of this.
So client has an exec channel (similar for a tcpip channel). Lets say that the client is able to send data much faster than the program at the other end (or socket peer in the case of a tcpip channel) will read it from its stdin stream. The window mechanism exists to ensure that it is the ssh client channel that blocks and backs up, protecting the SSH daemon (the SSH daemon discarding data that is sent out of the window by a rogue client attempting to crash the daemon), and allowing other channels from the same client to continue operating.
The bit I can't get clear in my mind is how the SSH daemon actually manages sending the SSH_MSG_CHANNEL_WINDOW_ADJUST message to the client. I mean what you really want to know is how much of the data the program has actually read from its buffers -- the window you are really trying to describe is that pipe between the SSH daemon and the program itself. But the SSH daemon clearly (?) can't know that.
Presumably all it can do is ensure that the file descriptors it is writing to are in non blocking mode and then notice the "EAGAIN" or "EWOULDBLOCK" and know what it has got some data left that it can't deliver immediately, and put a brake on the client by sending it a suitable SSH_MSG_CHANNEL_WINDOW_ADJUST. It then adds that data and file descriptor to a list that it retries periodically until it is successful and then releases the client with another WINDOW_ADJUST message?
Each channel can potentially end up in this state, but you are limited by the number of channels, so you will have one outstanding message per channel that you are waiting to try and deliver, and the buffer will be at most the packet size, so there doesn't seem to be any danger to the daemon in doing this, running out of memory, etc.
Is that the basic mechanism by which openSSH works in this regard?
Again, apologies if this is not an appropriate question for this list.
More information about the openssh-unix-dev