-
Notifications
You must be signed in to change notification settings - Fork 280
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] [RFC] Multistream-2.0 #95
Closed
Closed
Changes from 1 commit
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
1043853
[WIP] [RFC] Multistream-2.0
Stebalien c92c58c
second iteration of the multistream-2.0 spec
Stebalien dbb3ec2
fix incomplete sentence
Stebalien 6a16dc0
clarify some things
Stebalien d8cfdc7
clarifications from CR
Stebalien 1278c7f
multistream: resolve some questions/discussions
Stebalien 75ca7ca
drop speculative stream
Stebalien 8ea2f40
multistream: nit
Stebalien e273037
fix formatting
Stebalien fcc5ac3
multistream: improve naming
Stebalien 1ccfa7b
multistream: update unidirectional comment
Stebalien 3983557
multistream: clarify serial stream reset
Stebalien eeaea23
multistream: add a protocol for handling simultanious open
Stebalien 5e3aa0d
multistream: add some examples to the TCP simultanious open stuff
Stebalien 3c61282
Add proposal for packet oriented extensions
bigs File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -187,6 +187,75 @@ Importantly: When we switch to multistream 2.0, we'll tag the connection (and | |
any sub connections) with the multistream version. This way, we never have to do | ||
this again. | ||
|
||
## TCP Simultaneous Open | ||
|
||
As noted in the [retrospective](retrospective.md), multistream 1.0 doesn't | ||
provide any way to distinguish between the initiator and the receiver of a | ||
stream. Multistream 2.0 doesn't either but it *does* allow us to handle the TCP | ||
Simultaneous Open case without needing any additional round-trips in the fast | ||
path. | ||
|
||
To make this work, we need a new protocol: "duplex-stream" (or whatever we want | ||
to call it). This protocol allows one to bind two unidirectional streams | ||
together into a single bidirectional stream. | ||
|
||
### Protocol | ||
|
||
The protocol is: | ||
|
||
1. The side that wants to be the "initiator" of a duplex stream sends a | ||
"initiate stream ID" message (where ID is randomly generated 256 bit number). | ||
2. The receiver sends back "receive stream ID" on a different unidirectional stream. | ||
3. The two streams are now joined. | ||
|
||
More specifically, | ||
|
||
1. The initiator sends: `<multistream/multicodec><duplex-stream>0<32 bytes of randomness>` | ||
1. The receiver sends: `<multistream/multicodec><duplex-stream>1<the same 32 bytes of randomness>` | ||
|
||
If we end up in a situation where both peers want to be the initiator of a | ||
single pair of unidirectional streams, the peer that picks the *lower* random ID | ||
should back off and act as the receiver. | ||
|
||
### Usage | ||
|
||
We treat each new TCP connection as a pair of unidirectional streams and use | ||
this protocol to bind them together. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we need full detail on the wire for this, all the way up to secio negotiation (both cases). |
||
|
||
On connect, the initiator(s) will: | ||
|
||
1. Use `serial-stream` to make the stream recoverable. | ||
2. Inside that "serial stream", it'll do the initiator half of the stream | ||
handshake. | ||
3. It'll then start the security negotiation as usual. | ||
|
||
If there is a receiver, it will: | ||
|
||
1. Handle the serial stream. | ||
2. See the "duplex stream initiate". | ||
3. Send a "duplex stream receive" on the other stream. | ||
4. Handle the security negotiation. | ||
|
||
If there are two initiators, they will both. | ||
|
||
1. Handle the serial stream. | ||
2. See the "duplex stream initiate" message. | ||
3. Reset their outbound streams, dropping out of serial stream. | ||
4. The side with the *larger* `RANDOM ID` will try again as the initiator. The | ||
side with the smaller will switch to the receiver role. | ||
|
||
In practice, both sides should actually be quite a bit more flexible here. That | ||
is, they should handle protocols as they're negotiated by the other peer instead | ||
of simply *assuming* that the other peer will negotiate a specific protocol. | ||
|
||
For example, peers may want to send a bunch of unidirectional protocol | ||
advertisements before switching to duplex mode. One or both sides may decide to | ||
*not* use serial-stream to make the underlying connection recoverable (or they | ||
may use it multiple times recursively). | ||
|
||
In other words, both sides should actually treat the read half of the TCP stream | ||
as if it were an inbound unidirectional stream until it's not. | ||
|
||
## Example | ||
|
||
So, that was way too much how and not enough why or WTF? Let's try an example | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@vyzo, @jhiesey
This is my proposal for handling simultaneous open. TL;DR: The connection has two unidirectional streams until they're joined.
@vyzo IIRC, this is slightly different from the protocol we discussed as we always use it, even if we have no reason to believe we performed a simultaneous connect.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM but we need more wire detail on the examples.
So let's have two examples with full protocol detail, one for the common case and one for simultaneous open.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SGTM.