|
@@ -1,4 +1,136 @@
|
|
|
-yamux
|
|
|
-=====
|
|
|
+# Yamux
|
|
|
+
|
|
|
+Yamux or Yet another Mux (Multiplexer) is another multiplexing
|
|
|
+library. It relies on an underlying connection to provide reliability
|
|
|
+and ordering (such as TCP or Unix domain sockets), and provides
|
|
|
+stream-oriented multiplexing. It is inspired by SPDY but is not
|
|
|
+interoperable with it.
|
|
|
+
|
|
|
+Yamux features include:
|
|
|
+* Bi-directional streams created by either client or server
|
|
|
+* Flow control, this prevents a single flow from starving others
|
|
|
+* Transparent compression
|
|
|
+
|
|
|
+# Framing
|
|
|
+
|
|
|
+Yamux uses a streaming connection underneath, but imposes a message
|
|
|
+framing so that it can be shared between many logical streams. Each
|
|
|
+frame contains a header like:
|
|
|
+
|
|
|
+<Version> (4 bits)
|
|
|
+<Type> (4 bits)
|
|
|
+<Flags> (8 bits)
|
|
|
+<StreamID> (32 bits)
|
|
|
+<Length> (32 bits)
|
|
|
+
|
|
|
+This means that each header has a 10 byte overhead. Each field
|
|
|
+is described below:
|
|
|
+
|
|
|
+## Version Field
|
|
|
+
|
|
|
+The version field is used for future backwards compatibily. At the
|
|
|
+current time, the field is always set to 0, to indicate the initial
|
|
|
+version.
|
|
|
+
|
|
|
+## Type Field
|
|
|
+
|
|
|
+The type field is used to switch the frame message type. The following
|
|
|
+message types are supported:
|
|
|
+* 0x0 Data - Used to transmit data. May transmit zero length payloads
|
|
|
+ depending on the flags.
|
|
|
+
|
|
|
+* 0x1 Window Update - Used to updated the senders receive window size.
|
|
|
+ This is used to implement per-session flow control.
|
|
|
+
|
|
|
+* 0x2 Ping - Used to measure RTT. It can also be used to heart-beat
|
|
|
+ and do keep-alives over TCP.
|
|
|
+
|
|
|
+* 0x3 Go Away - Used to close a session.
|
|
|
+
|
|
|
+## Flag Field
|
|
|
+
|
|
|
+The flags field is used to provide additional information related
|
|
|
+to the message type. The following flags are supported:
|
|
|
+
|
|
|
+* 0x1 SYN - Signals the start of a new stream. May be sent with a data or
|
|
|
+ window update message.
|
|
|
+
|
|
|
+* 0x2 ACK - Acknowledges the start of a new stream. May be sent with a data
|
|
|
+ or window update message.
|
|
|
+
|
|
|
+* 0x4 FIN - Performs a half-close of a new stream. May be sent with a data
|
|
|
+ message or window update.
|
|
|
+
|
|
|
+* 0x8 RST - Reset a stream immediately. Sent with a data message only.
|
|
|
+
|
|
|
+* 0x 16 LZW - Indicates the payload is LZW compressed. Sent with a data message
|
|
|
+ only.
|
|
|
+
|
|
|
+## StreamID Field
|
|
|
+
|
|
|
+The StreamID field is used to identify the logical stream the frame
|
|
|
+is addressing. The client side should use odd ID's, and the server even.
|
|
|
+This prevents any collisions. Additionally, the 0 ID is reserved to represent
|
|
|
+the session.
|
|
|
+
|
|
|
+Both Ping and Go Away messages should always use the 0 StreamID.
|
|
|
+
|
|
|
+A Window Update may also provide StreamID 0, meaning the window for
|
|
|
+the entire session is being modified.
|
|
|
+
|
|
|
+## Length Field
|
|
|
+
|
|
|
+The meaning of the length field depends on the message type:
|
|
|
+* Data - provides the length of bytes following the header
|
|
|
+* Window update - provides a delta update to the window size
|
|
|
+* Ping - Contains an opaque value, echoed back
|
|
|
+* Go Away - Contains an error code
|
|
|
+
|
|
|
+# Message Flow
|
|
|
+
|
|
|
+There is no explicit connection setup, as Yamux relies on an underlying
|
|
|
+transport to be provided. However, there is a distinction between client
|
|
|
+and server side of the connection.
|
|
|
+
|
|
|
+## Opening a stream
|
|
|
+
|
|
|
+To open a stream, an initial data or window update frame is sent
|
|
|
+with a new StreamID. The SYN flag should be set to signal a new stream.
|
|
|
+
|
|
|
+The receiver must then reply with either a data or window update frame
|
|
|
+with the StreamID along with the ACK flag to accept the stream or with
|
|
|
+the RST flag to reject the stream.
|
|
|
+
|
|
|
+## Closing a stream
|
|
|
+
|
|
|
+To close a stream, either side sends a data or window update frame
|
|
|
+along with the FIN flag. This does a half-close indicating the sender
|
|
|
+will send no further data.
|
|
|
+
|
|
|
+Once both sides have closed the connection, the stream is closed.
|
|
|
+
|
|
|
+Alternatively, if an error occurs, the RST flag can be used to
|
|
|
+hard close a stream immediately.
|
|
|
+
|
|
|
+## Flow Control
|
|
|
+
|
|
|
+When Yamux is initially started there is a 2MB window size for
|
|
|
+the session. Additionally, each new stream has a 256KB window size.
|
|
|
+
|
|
|
+To prevent the session or streams from stalling, window update
|
|
|
+frames should be sent regularly. Yamux can be configured to provide
|
|
|
+a limit for windows sizes.
|
|
|
+
|
|
|
+Both sides should track the number of bytes sent in Data frames
|
|
|
+only, as only they are tracked as part of the window size.
|
|
|
+
|
|
|
+## Session termination
|
|
|
+
|
|
|
+When a session is being terminated, the Go Away message should
|
|
|
+be sent. The Length should be set to one of the following to
|
|
|
+provide an error code:
|
|
|
+
|
|
|
+* 0x0 Normal termination
|
|
|
+* 0x1 Protocol error
|
|
|
+* 0x2 Internal error
|
|
|
|
|
|
-Golang connection multiplexing library
|