Security API/TCPM Framing
From The Open Source Backup Wiki (Amanda, MySQL Backup, BackupPC)
When multiplexing multiple security streams over the same operating-system stream (e.g., a socket or pipe), Amanda uses TCPM Framing, which presumably stands for "TCP Multiplexing".
Each stream is assigned a distinct, numeric handle. In practice, all streams are initiated by the same end of the connection, so as far as I (Dustin) know there is no provision for ensuring that handles invented by the two ends do no collide. Each frame of data for each stream is transmitted with the following format:
32-bit signed network-order payload length 32-bit unsigned network-order handle payload
Amanda considers a negative length or a length greater than 4MB to be invalid and will close the connection with an error. As another implementation detail, Amanda will display any printable bytes in the error message, so if e.g., shell or ssh error messages are accidentally injected into the operating-system stream, the user will see at least part of the messages.
A zero-length frame indicates EOF for that stream.
For random-access streams, data boundaries are not relevant and the API does not guarantee they will be maintained - much like with ordinary pipes or sockets.
The first frame sent over a new connection is assumed to be a protocol packet, and the handle from the frame is retained and reserves that stream for protocol communication. The stream is closed (empty packets in each direction) when the protocol transaction is complete. Each protocol packet is contained in a single, distinct frame; that is, the framing boundaries are relevant to the protocol.
My (Dustin) understanding is that the protocol does not technically support multiple protocol transactions on the same connection, but through a series of reference-counting bugs in security-util.c and some timing coincidences in protocol.c, it happens to work. Subsequent protocol transactions take place on new handles, which amandad recognizes as such (due to a refcounting bug, a pointer to amandad's protocol_recv function is still in the security handle, and it gets called for the incoming packet)
To formalize that:
- from amandad's perspective, any data arriving on an unrecognized handle when no other handles are open should be assumed to begin a new protocol conversation