Specification for providing the bpmux abstractions over an ordered, reliable, bidirectional communication channel, such as tcp or unix domain sockets.
Bpmux/rel asigns 64 bit identifiers to all entities, so that packets can be "routed" to the correct entities. It also keeps track of whether an entity was created by the endpoint itself (out-entities) or by the peer (in-entities), to prevent trouble when both parties create entities with the same identifier concurrently.
Data gets transmitted in chunks. Each chunk begins with a 1-byte tag, followed by a VarU64 encoding the identifier of an identity, followed by additional bytes whose interpretation depends on the tag. The tag consists of three bits for the type, followed by five bits of flags.
The type indicates what kind of entity the identifier following the tag refers to:
bits | type |
---|---|
000 | Out-Request |
001 | In-Request |
010 | Out-Sink |
011 | In-Sink |
100 | Out-Stream |
101 | In-Stream |
110 | Duplex |
111 | Partial |
The flags are (from fourth-most-significant to least significant bit):
payload
credit
ping
end
ack-end
Unless otherwise noted:
- identifiers are always unsigned 64 bit integers, and when transmitted, they are encoded as VarU64s
- payloads are byte strings of length up to 2^64 - 1, and are encoded as a VarU64 followed by that many bytes
- credits are always unsigned 64 bit integers, and when transmitted, they are encoded as VarU64s
- end-payloads work just like regular payloads, except they are indicated by the
end
flag
To send a new request, choose an identifier not in the set of out-requests
and send a chunk of type Out-Request
. The payload
flag must be set, the credit
, ping
and end
flags may be set, and the ack-end
flag must not be set. The tag byte is followed by the chosen identifier, followed by the payload, optionally followed by the credit, optionally followed by the end-payload. Add the identifier to the out-requests
. If credit was sent, add that much credit to the entry.
To cancel an out-request, send a chunk of type Out-Request
, with the end
flag set. Mark the corresponding entry in the out-requests
as awaiting end acknowledgement.
Upon receiving a packet of type Out-Request
, check whether there is already an entry of the correct identifier in your in-requests
map. If there is not, and the payload
flag is not set, this is an error. If the flag is set, add an entry to the map, with the appropriate credit. If the end
flag was set, immediately send back an ack-end
chunk of type In-Request
and with the identifier.
If there is already an entry for the identifier in your in-requests
map, and payload
is set, this is an error. Else, update credit if the credit
flag is set, or send back an ack-end
chunk i the end
packet is set.