ttmxm is a dead simple application forwarding protocol with support for basic session management; aka. multiuser ssh smashed together with something like abduco.
It is flexible enough that it can forward all sorts of program that require input and have an output, like:
- a terminal
- gdb
- a REPL
- a socket; this includes stuff from Docker up to the X11 socket (read Forwarding graphics)
It works on top of QUIC, a reliable and fast transport system that works on top of UDP, so it feels smooth to use.
ttmxm is made for a whole different market than ssh, mosh, or telnet, and is not meant to replace it but just to coexist with it
Forwarding graphics
ttmxm is generic enough that most UNIX sockets can run on top of it, provided that the server assumes that the client cannot magically access files it does not know about but the server can.
In the X11 days, the designers assumed the server doesn’t necessarily run on the same machine as the client, and that is why it is mostly forwardable via ssh or ttmxm, but Wayland does assume the compositor is on the same machine as the client, so it relies on a lot of Linux API stuff, and passing buffers… without copying them. This makes it really hard to forward.
Basically, X11 does is like going to a restaurant and teaching the chefs how to make your pizza, while Wayland is asking the the waiters to get a pizza from your home, present it, and put in your table: we can’t just forward your house! Only the restaurant.
Differences with similar protocols
There are a trillion protocols that already let me connect to a terminal, there is telnet, there is ssh, there is mosh, …, so why another one?
ttmxm is meant for really long lived sessions, and allows you to dettach and attach to your session as you need, if electricity cuts out, or the network drops, you can still reconnect and your session will still be there; no data lost.
ttmxm also allows multiple clients to connect to a single session; but only one can write. You can try to claim control (raising your hand in other applications) This is really helpful in situations like:
- interactive and dynamic online classes: teacher can hand control over to an student to type something and then take control back, so you don’t spend half the class debugging student missing an s and saying “here it says command not found!”,
- collaborative programming, obviously
- debugging production machines
- some sort of technical support
- playing online chess in the most nerdy way ever made
- clankers that could be configured as read-only and automatically report stuff, and still let other clients connect to the same terminal
- clankers programming together and an human reviewer
- (Dark humor incoming) conferences if COVID strikes again or something
Implementation
Not much effort is being put into the reference implementation, as right now I am trying to polish the protocol. It will be written in Golang.
Protocol
Although, as any good application-layer protocol, it can run over any transport providing TLS and multiplexed streams, which describes QUIC.
There are three “planes”, these not necessarily map to transport planes and are numbered:
- the “control plane” (no. 0), where control frames and notifications are exchanged
- the “input plane” (no. 1), where the Controller (explanation later) sends application input data
- the “output plane” (no. 2), where all clients read application output data
Clients have an state machine, they can be in any of these states:
CONNECTED: Client has connected, but no OPEN frame has been sent.OPEN: Client has sent an OPEN frame and the server successfuly recieved it, on this state, you can only recieve data from the Output plane, recieve informational responses from the server, sendOPENandPING, authenticate frames, and do capability negotiation.AUTHENTICATING: Client has authenticated and is now awaiting response from the server (this is a very ephemeral state, I know)ATTACHED: The client successfully authenticated. On this state, you are either:- the Controller: meaning you are able to write data on the input plane
- an Observer: meaning you are not the Controller (duh!)
CLOSED: You are logically not part of the session, even if you are still connected. You recieve this state after unsuccessful authorization or after sending aCLOSEframe. Note that you can become OPEN again by sending an OPEN frame.