Browse Source

README cleanup

Armon Dadgar 10 years ago
parent
commit
d8a2feb541
2 changed files with 218 additions and 121 deletions
  1. 77 121
      README.md
  2. 141 0
      spec.md

+ 77 - 121
README.md

@@ -1,130 +1,86 @@
 # Yamux
 # Yamux
 
 
-Yamux or Yet another Mux (Multiplexer) is another multiplexing
-library. It relies on an underlying connection to provide reliability
+Yamux or Yet another (Multiplexer is a multiplexing library for Golang.
+It relies on an underlying connection to provide reliability
 and ordering (such as TCP or Unix domain sockets), and provides
 and ordering (such as TCP or Unix domain sockets), and provides
 stream-oriented multiplexing. It is inspired by SPDY but is not
 stream-oriented multiplexing. It is inspired by SPDY but is not
 interoperable with it.
 interoperable with it.
 
 
 Yamux features include:
 Yamux features include:
-* Bi-directional streams created by either client or server
-* Flow control, this prevents a single flow from starving others
 
 
-# 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 (8 bits)
-* Type (8 bits)
-* Flags (16 bits)
-* StreamID (32 bits)
-* Length (32 bits)
-
-This means that each header has a 12 byte overhead.
-All fields are encoded in network order (big endian).
-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. Also sent with a ping to indicate outbound.
-
-* 0x2 ACK - Acknowledges the start of a new stream. May be sent with a data
-  or window update message. Also sent with a ping to indicate response.
-
-* 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.
-
-## 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.
-
-## 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 starts each stream with a 256KB window size.
-There is no window size for the session.
-
-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
+* Bi-directional streams
+  * Streams can be opened by either client or server
+  * Useful for NAT traversal
+  * Server-side push support
+* Flow control
+  * Prevents a flow from starving others
+  * Back-pressure to prevent overwhelming a receiver
+* Keep Alives
+  * Enables persistent connections over a load balancer
+* Efficient
+  * Yamux enables thousands of logical streams with low overhead
+
+## Documentation
+
+For complete documentation, see the associated [Godoc](http://godoc.org/github.com/hashicorp/yamux).
+
+## Specification
+
+The full specification for Yamux is provided in the `spec.md` file.
+It can be used as a guide to implementors of interoperable libraries.
+
+## Usage
+
+Using Yamux is remarkably simple:
+
+```go
+
+func client() {
+    // Get a TCP connection
+    conn, err := net.Dial(...)
+    if err != nil {
+        panic(err)
+    }
+
+    // Setup client side of yamux
+    session, err := yamux.Client(conn, nil)
+    if err != nil {
+        panic(err)
+    }
+
+    // Open a new stream
+    stream, err := session.Open()
+    if err != nil {
+        panic(err)
+    }
+
+    // Stream implements net.Conn
+    stream.Write([]byte("ping"))
+}
+
+func server() {
+    // Accept a TCP connection
+    conn, err := listener.Accept()
+    if err != nil {
+        panic(err)
+    }
+
+    // Setup server side of yamux
+    session, err := yamux.Server(conn, nil)
+    if err != nil {
+        panic(err)
+    }
+
+    // Accept a stream
+    stream, err := session.Accept()
+    if err != nil {
+        panic(err)
+    }
+
+    // Listen for a message
+    buf := make([]byte, 4)
+    stream.Read(buf)
+}
+
+```
 
 

+ 141 - 0
spec.md

@@ -0,0 +1,141 @@
+# Specification
+
+We use this document to detail the internal specification of Yamux.
+This is used both as a guide for implementing Yamux, but also for
+alternative interoperable libraries to be built.
+
+# 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 (8 bits)
+* Type (8 bits)
+* Flags (16 bits)
+* StreamID (32 bits)
+* Length (32 bits)
+
+This means that each header has a 12 byte overhead.
+All fields are encoded in network order (big endian).
+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. Also sent with a ping to indicate outbound.
+
+* 0x2 ACK - Acknowledges the start of a new stream. May be sent with a data
+  or window update message. Also sent with a ping to indicate response.
+
+* 0x4 FIN - Performs a half-close of a stream. May be sent with a data
+  message or window update.
+
+* 0x8 RST - Reset a stream immediately. May be sent with a data or
+  window update message.
+
+## 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.
+
+## 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.
+
+Because we are relying on the reliable stream underneath, a connection
+can begin sending data once the SYN flag is sent. The corresponding
+ACK does not need to be received. This is particularly well suited
+for an RPC system where a client wants to open a stream and immediately
+fire a request without wiating for the RTT of the ACK.
+
+This does introduce the possibility of a connection being rejected
+after data has been sent already. This is a slight semantic difference
+from TCP, where the conection cannot be refused after it is opened.
+Clients should be prepared to handle this by checking for an error
+that indicates a RST was received.
+
+## 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 starts each stream with a 256KB window size.
+There is no window size for the session.
+
+To prevent the streams from stalling, window update frames should be
+sent regularly. Yamux can be configured to provide a larger limit for
+windows sizes. Both sides assume the initial 256KB window, but can
+immediately send a window update as part of the SYN/ACK indicating a
+larger window.
+
+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
+