22
33> The spec for the friendly Stream Multiplexer (that works in 3 languages!)
44
5- | Lifecycle Stage | Maturity | Status | Latest Revision |
6- | -----------------| ----------------| --------| -----------------|
7- | 3A | Recommendation | Active | r0, 2018-10-10 |
5+ | Lifecycle Stage | Maturity | Status | Latest Revision |
6+ | -----------------| ----------------| ------------ | -----------------|
7+ | 3A | Recommendation | Deprecated | r0, 2018-10-10 |
88
99Authors: [ @daviddias ] , [ @Stebalien ] , [ @tomaka ]
1010
@@ -25,16 +25,17 @@ and spec status.
2525## Table of Contents
2626
2727- [ mplex] ( #mplex )
28- - [ Table of Contents] ( #table-of-contents )
29- - [ Overview] ( #overview )
30- - [ Message format] ( #message-format )
31- - [ Flag Values] ( #flag-values )
32- - [ Protocol] ( #protocol )
33- - [ Opening a new stream] ( #opening-a-new-stream )
34- - [ Writing to a stream] ( #writing-to-a-stream )
35- - [ Closing a stream] ( #closing-a-stream )
36- - [ Resetting a stream] ( #resetting-a-stream )
37- - [ Implementation notes] ( #implementation-notes )
28+ - [ Table of Contents] ( #table-of-contents )
29+ - [ Overview] ( #overview )
30+ - [ Deprecation Notice] ( #deprecation-notice )
31+ - [ Message format] ( #message-format )
32+ - [ Flag Values] ( #flag-values )
33+ - [ Protocol] ( #protocol )
34+ - [ Opening a new stream] ( #opening-a-new-stream )
35+ - [ Writing to a stream] ( #writing-to-a-stream )
36+ - [ Closing a stream] ( #closing-a-stream )
37+ - [ Resetting a stream] ( #resetting-a-stream )
38+ - [ Implementation notes] ( #implementation-notes )
3839
3940## Overview
4041
@@ -50,6 +51,41 @@ Implementations in:
5051- [ Go] ( https://github.com/libp2p/go-mplex )
5152- [ Rust] ( https://github.com/libp2p/rust-libp2p/tree/master/muxers/mplex )
5253
54+ ## Deprecation Notice
55+
56+ ** mplex is deprecated** for applications requiring resiliency and liveness.
57+ Users should ** prefer QUIC or Yamux** .
58+
59+ ** Core limitation: lack of stream flow control**
60+
61+ mplex does not support stream-level flow control, preventing receivers from
62+ applying backpressure. This leads to issues varying from easy to exploit DoS
63+ vulnerabilities due to unbounded sender behavior to hard to debug application
64+ stalls caused by a single slow stream receiver.
65+
66+ ** Additional Shortcomings** :
67+ - No stream-level flow control.
68+ - No way for a reader to backpressure a sender.
69+ - No good solution for slow readers.
70+ - Implementations generally do some combination of these mitigations:
71+ - Reset the stream once we reach a certain amount of unread buffered data.
72+ [ source] ( https://github.com/libp2p/rust-libp2p/blob/1c9b3ca355aecffa0bcf83d2495cd4cc1019425b/muxers/mplex/src/config.rs#L118 )
73+ - Block operations until the full stream is read from.
74+ [ source] ( https://github.com/libp2p/rust-libp2p/blob/1c9b3ca355aecffa0bcf83d2495cd4cc1019425b/muxers/mplex/src/config.rs#L130 )
75+ - Block up to a certain amount of time, then reset the stream.
76+ [ source] ( https://github.com/libp2p/go-mplex/blob/ad9bfb922974b5875cc48c6e7492c4987c0cb94a/multiplex.go#L35-L37 )
77+ - Head of line blocking between streams
78+ - For example, No way to interleave data from streams if one stream makes a
79+ big write, and another stream has a small write
80+ - A single slow reader of a single stream can stall the whole application and TCP connection.
81+ - No way of propagating errors.
82+ - Errors that could explain why a peer reset the stream.
83+ - No way to signal to a peer that you will not read any more data (e.g. QUIC's
84+ STOP_SENDING frame).
85+ - Both sides can open streams with the same ID, differing only by who opened the
86+ stream. which may lead to confusion.
87+ - stream names are relatively unused (go-libp2p does not use them. I don't think rust-libp2p or js-libp2p uses them either)
88+
5389## Message format
5490
5591Every communication in mplex consists of a header, and a length prefixed data segment.
0 commit comments