-
Notifications
You must be signed in to change notification settings - Fork 291
Description
Yamux does not offer any form of control in how many streams can be opened by a remote.
This has been an annoyance for a while and transports like QUIC are useful because they do support managing the number of open streams.
I'd like to propose what I believe is a backwards-compatible extension of the yamux spec that gives us some amount of back-pressure for streams.
The yamux specification states for opening of a new 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.
My proposal is as follows:
Implementations SHOULD keep track of how many streams are pending, i.e. they have not yet received an
ACKfor this stream. When receivingRSTfor a pending stream, implementations SHOULD take note of the number of currently pending streams as a "pending stream budget". For the remainder of the connection, implementations SHOULD NOT exceed this budget.
Implementations MUST NOT assume for this budget to be a constant but shrink it in case the remote peer keeps sendingRSTflags for pending streams.
I think this is backwards-compatible because existing implementations already need to handle receiving RST for a stream at any point. What we are doing here is adding meaning to receiving RST whilst we have several pending substreams. This allows us to implement a bounded buffer on the receiver side where any streams exceeding that buffer will send a RST and be dropped. This means we will have 1 failed stream per physical connection that allows us to learn the other party's buffer size.