Repository navigation
Deliver SSH events in the order libssh raises them - #15
Merged
Merged
Conversation
libssh also dispatches inbound packets inside our Client and ServerSession methods: ssh_message_get in session_drive and the flush in ssh_channel_write both poll the socket. Events raised there waited in the session actor's outbox until its message completed, and data raised in the meantime from the event loop reached the receiver first, so pipe streams arrived reordered under load. Send every event with no current actor, so it is appended to the receiver's mailbox when libssh raises it. Add a test that checks the byte order of pipelined pipe traffic in both directions.
One run of the pipe order test takes longer than 10 s on the CI runners.
acton test shows a test's output only when it fails or times out, so the lines tell where a slow run spent its time.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
libssh dispatches inbound packets whenever one of its calls polls the socket, and acton-ssh makes such calls from inside Client and ServerSession methods as well as from the event loop. On the server, ssh_message_get in session_drive polls on every call, and on both sides the flush at the end of ssh_channel_write polls when a send left bytes buffered. A channel event raised inside one of those methods was sent while the session actor was the current actor, so it waited in that actor's outbox until the actor's message completed. If the worker went back to the event loop before then, the poll callback appended newer data straight to the receiver's mailbox and the older data arrived after it. Under load this reordered pipe streams, and NETCONF sessions saw a chunk header followed by bytes from a later message.
With this change every event is sent with no current actor, the way events raised from the event loop already were, so each one is appended to its receiver's mailbox when libssh raises it. All libssh calls for a session run on the thread that owns it, so each mailbox receives events in the order libssh raised them.
The new test runs eight pipes with pipelined three-write frames in both directions and checks every byte received. Without the change it failed 19 of 20 runs; with it, it passed 20 of 20.