Go to the first, previous, next, last section, table of contents.


The remote protocol

This chapter documents the protocol between fshd and in.fshd. This protocol is normally only of interest to the developer of fsh, and may be a little out of date.

In the description below, fshd is the client and in.fshd is the server. You can try out the protocol manually if you like by starting in.fshd interactively. In the example, the text that is output by in.fshd appears after the print symbol `-|'.

bash$ in.fshd
 -| fsh 1
new 2 8Hcat -vet
stdin 2 4Hfoo

 -| stdout 2 5Hfoo$
 -| 
eof-stdin 2
 -| eof-stdout 2
 -| eof-stderr 2
 -| exit 2 1H0
 -| eos 2

Basic syntax

The protocol assumes an 8-bit-clean connection. All commands (except the initial greeting) have the same overall structure. This protocol uses ASCII, but it is capable of transmitting any byte-stream.

Some commands require the data chunk, while others don't allow it. There is no command that only uses a data chunk sometimes.

Connection establishment

The server starts by sending a greeting to the client. This is the only thing that doesn't adhere to the basic syntax. It contains the word `fshd' followed by the version number of the protocol, which is 1. The client does not respond.

fsh 1

Session management

Each command that should be executed is contained in a session. There can be several simultaneous sessions. The client associates each session with a unique session id, which is an integer.

A new session is created by sending a new command to the server.

new session-id command

The command is a string, suitable to pass to your login shell on the remote system.

Once a session is established data can be sent by either the client or the server. The client uses stdin to send data. The server uses stdout or stderr. The format of these three commands is the same:

stdin session-id strlenHdata
stdout session-id strlenHdata
stderr session-id strlenHdata

strlen is a decimal string, that specifies how long data is. The data can contain any byte, including NUL, newline and carriage return.

The client can send signals to the session:

signal session-id signal-name

The following values are defined for signal-name:

End-of-file can be specified for each of the three data channels separately:

eof-stdin session-id
eof-stdout session-id
eof-stderr session-id

When the child dies the server will send the exit status to the client.

exit session-id exit-status
signal-exit session-id signal-name

The core-dumped flag is 1 if a core file was generated, 0 if no core was generated (or if the remote implementation is unable to determine if a core was generated or not). Please note, however, that the flag is not currently sent over the protocol.

Session termination

The server always sends an end-of-session to the client when it discards a session.

eos session-id

The eos will be generated spontaneously by the server when it has sent eof-stdout, eof-stderr and one of exit or signal-exit. The client should never reuse a session id until it has seen an eos from the server.

The client can also request that the session is terminated by sending an eos to the server. This should only be used in abnormal situations, such as if the fsh program responsible for this session unexpectedly died (indicating that there is nobody awaiting the result of the program). When the server receives an eos it will kill the program (with something similar to kill -KILL pid) if it is alive, close all ptys to the program (without trying to drain them), and send back an eos response to the client as confirmation.

Flow control

To avoid pileup of unprocessed data in the endpoints (stdin data in in.fshd and stdout/stderr data in fsh) a strict flow control protocol must be adhered to.

When a session is created it is initially allowed to send 128 KB (that is, 131072 bytes) to the stdin of the remote system. When it receives an stdin-flow statement the limit is increased to the value sent in it. The fsh process is responsible for counting the bytes and pause if it doesn't receive an stdin-flow statement in time. The in.fshd process is responsible for sending stdin-flow statements. They should ideally be sent in advance, so that in.fshd always maintains a buffer of pending input to the process.

Similarly, in.fshd may only send 128 KB of stdout data and 128 KB of stderr data, until it receives stdout-flow and stderr-flow commands from fsh.

stdin-flow session-no new-limit
stdout-flow session-no new-limit
stderr-flow session-no new-limit

Please note that fshd is not directly involved in the flow control protocol. It only relays messages between all the fsh processes an the in.fshd process.

These limits exists so that both in.fshd and all fsh processes always should be able to read anything that fshd wants to send to them. The initially allowed window of 128 KB is included so that a new session can start sending data at once, without a need for any round-trip delay.


Go to the first, previous, next, last section, table of contents.