Armon Dadgar 10 lat temu
rodzic
commit
d8a2feb541
2 zmienionych plików z 218 dodań i 121 usunięć
  1. 77 121
      README.md
  2. 141 0
      spec.md

+ 77 - 121
README.md

@@ -1,130 +1,86 @@
 # 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
 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
 
-# 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
+