BebboSSH AROS 1.0.8: handling stalled clients

On this page

BebboSSH AROS 1.0.8, released on October 29, 2026 for i386, x86_64 and aarch64, addresses an unglamorous but essential part of remote access: a client that stops receiving data must not leave the server stuck forever. In my AROS port of BebboSSH, I focused this release on daemon robustness, not a new full-featured shell or a change of cryptographic algorithms.

The project derives from BebboSSH by Stefan “Bebbo” Franke. The AROS port is my derivative work, released under GPLv3 or later with upstream credits preserved. Compared with 1.0.7, which also addressed PuTTY and WinSCP compatibility, the focus here is how the service responds when a connection misbehaves.

The client stops reading: why everything stalled

In the send path, a socket that is temporarily not writable returns EAGAIN. That does not necessarily mean a lost connection: the buffer may simply be full. The routine retried, but without a bound on the lack of progress. If the recipient stopped reading, the daemon could remain in that loop, preventing new logins and service to other sessions.

In 1.0.8 the send is abandoned after 30 seconds without progress; successfully sending more bytes resets the stall timer. Ctrl-C is also checked during the stall. Failure marks the session dead, and it is subsequently closed outside the channel callback. This protects against an endless wait; it is not a promise that transfers always finish within 30 seconds.

The fix does not magically make every server path asynchronous: other work can still be delayed during the wait. The practical difference is that a connection which no longer consumes output cannot monopolize that loop indefinitely.

Keep-alives and network waits: two more edge cases

With SendNoop some or many, the code assumed that channel 0 still existed. If that channel had closed while another remained open, the keep-alive used the wrong reference: the x86_64 notes document a crash, while on i386 the client disconnected. The first actually open channel is now selected. The option remains off by default.

A failed WaitSelect() could also be interpreted as every socket being readable and Ctrl-C being pressed. The daemon now logs the error, discards unvalidated descriptors and resumes its loop; a temporarily unavailable read is no longer automatically treated as a closed session. These event-loop details separate a recoverable error from a disappearing service.

What differs between the three architectures

  • i386 alt-abiv0 and aarch64: the key-exchange timing pad is corrected: it previously waited 2.5 times less than intended. The measured interval also handles a clock moving backwards and caps a single duration used in the calculation at five seconds.
  • i386: the client frees the keyboard.device request used to read keyboard qualifiers. Previously, a small allocation leaked in runs using that path, for example after the first cursor key.
  • Validation scripts: BEBBOSSH_AROS_AUTH_HELPER=askpass passes the password to OpenSSH through SSH_ASKPASS. This is an alternative for testing, not a new SSH protocol mode; the default remains sshpass.

What was verified, and what was not

The release notes document tests using the public archives on AROS One i386 and x86_64 under QEMU, and on a Raspberry Pi 400 running the September 12, 2026 AROS raspi-aarch64 build. They report 100/100 logins, 80/80 stress transfers without delays between connections, SFTP uploads from 1 to 16 MiB, and checks covering authentication, malformed requests and direct-tcpip forwarding.

For the main defect, the notes describe a client which stops reading during 16 MiB of command output: a new login becomes possible after the stall bound, and Ctrl-C during the stall stops the daemon within two seconds in the reported tests. While preparing this article, I reviewed the code and downloaded all six ZIP/TAR.GZ archives, checking their integrity and published SHA-256 values. I did not rerun the AROS tests here: runtime results are those documented for the release, not a new validation session.

The limitations that still matter

There is still no full interactive PTY shell or support for pipes and redirection in remote commands. On i386 and aarch64, a command launched inside an interactive session can block other connections until it finishes; for long operations, prefer ssh host command, which runs in a separate task. Even there, the 30-second timeout with status 124 does not kill the command: it continues until it ends. This is separate from the new stalled-send limit.

On x86_64/mincrt, remote execution remains synchronous: keep commands short. Requesting an unmounted volume through SFTP can open a requester on the AROS screen and block the daemon. Under heavy load, the e1000 driver issue described in the notes is separate from BebboSSH: use rtl8139 or pcnet until the distribution includes the upstream fix. On the Pi 400, avoid console debug logging with -v5 during heavy transfers, a scenario that froze the system in the documented tests.

OpenSSH put -p still does not preserve the timestamp, and a channel-close message sent first by the client remains a limitation. On i386 the daemon offers only aes128-gcm@openssh.com unless a Ciphers line is configured; on x86_64, HomeDir and some SFTP features still require the opt-ins described in the notes.

Download BebboSSH AROS 1.0.8

All three tags point to release commit e0df1b9, but contain binaries for different architectures. Later default-branch commits update script defaults and support links: they are not new features in the 1.0.8 packages. All three Aminet pages also show version 1.0.8 as checked on November 1.

Platform GitHub archives Aminet
i386 ABI v0 ZIP / TAR.GZ Page
x86_64 mincrt ZIP / TAR.GZ Page
Raspberry Pi aarch64 ZIP / TAR.GZ Page

Before starting the service

The kit includes the server, SSH/SCP clients, Ed25519 key generator, example configuration and instructions. Replace the test credentials in passwd before exposing the daemon, and follow README.AROS.txt to create the initial seed and then the host key. The AROS binaries are statically linked with libcryptossh.a: they do not require a separate installation of the similarly named Amiga library.

The practical purpose of 1.0.8 is to make a service I use as laboratory infrastructure more predictable. A successful login is only the beginning; recovery also matters when a client stalls, the network returns an error or a channel has already closed.

Sources and release notes

AUTHOR

IT specialist, developer and systems engineer with a long history across code, Linux servers, retrocomputers and e-learning platforms. On AndroidLab he brings a technical, pragmatic eye: less brochure smoke, more attention to infrastructure, usability, privacy, updates and the real consequences of manufacturers' choices.

Leave a Comment