Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix the channel window logic #292

Merged
merged 1 commit into from
Dec 19, 2022
Merged

Conversation

tomaswolf
Copy link
Member

The previous implementation would always reset the window to the maximum size when it had dropped to below half the maximum size.

This was wrong and defeated the purpose of having a window. The window size is reduced upon reception of the data, and incremented when the reader from the channel has read some data. With a slow reader and a fast sender, the window would be opened fully even if the reader had not read the previously accumulated data. As a result, internal buffers could exceed the window size by a lot.

(Consider the very good description in ChannelDataReceiver: if the exit toll booth always tells the entry the bridge was free again, far too many cars would be let onto the bridge. With a real bridge, there'd be a gigantic traffic jam; with Apache MINA sshd, the bridge (the internal buffers) would just get longer and longer.)

Change the algorithm to increase the window size only by as much as has actually been read by the channel reader. Use the same logic as OpenSSH: send a window adjustment message when the available size is smaller than half the full window size, or if more than three full SSH packets have been buffered.

To avoid sending a window adjustment for very small amounts, require a minimum size for the adjustment (more than half a packet, or more than a tenth of the full window, or more than 16kB -- because packet size and full window size are configurable, a single minimum value is not good enough.)

If there are multiple threads reading (for instance, one from stdout and one from stderr), make sure that normally only one will cause a window adjustment to be sent.

The previous implementation would always reset the window to the
maximum size when it had dropped to below half the maximum size.

This was wrong and defeated the purpose of having a window. The
window size is reduced upon reception of the data, and incremented
when the reader from the channel has read some data. With a slow
reader and a fast sender, the window would be opened fully even if
the reader had not read the previously accumulated data. As a result,
internal buffers could exceed the window size by a lot.

(Consider the very good description in ChannelDataReceiver: if the
exit toll booth always tells the entry the bridge was free again,
far too many cars would be let onto the bridge. With a real bridge,
there'd be a gigantic traffic jam; with Apache MINA sshd, the bridge
(the internal buffers) would just get longer and longer.)

Change the algorithm to increase the window size only by as much as
has actually been read by the channel reader. Use the same logic as
OpenSSH: send a window adjustment message when the available size is
smaller than half the full window size, or if more than three full SSH
packets have been buffered.

To avoid sending a window adjustment for very small amounts, require
a minimum size for the adjustment (more than half a packet, or more
than a tenth of the full window, or more than 16kB -- because packet
size and full window size are configurable, a single minimum value is
not good enough.)

If there are multiple threads reading (for instance, one from stdout
and one from stderr), make sure that normally only one will cause a
window adjustment to be sent.
@tomaswolf tomaswolf merged commit 78ed6bc into apache:master Dec 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant