-
Notifications
You must be signed in to change notification settings - Fork 283
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
The Circuit Relay Specification: The first iteration #15
Conversation
relay/README.md
Outdated
- `/p2p-circuit` | ||
- Use relay discovery to find a suitable relay node. (Neither specified nor implemented.) | ||
- Listen for relayed connections. | ||
- Dial through the discovered relay node for any `/p2p-circuit` multiaddr. | ||
|
||
TODO: figure out forced addresses. | ||
TODO: figure out nested relayed connections. | ||
TODO: figure out forced addresses. -> what is forced addresses? |
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.
@lgierth Can you elaborate on what "forced addresses" are?
relay/README.md
Outdated
- `/p2p/QmRelay/p2p-circuit` | ||
- Same as previous example, but use peer routing to find an address for QmRelay. | ||
|
||
?? I believe we don't need this one: | ||
- `/p2p-circuit` | ||
- Use relay discovery to find a suitable relay node. (Neither specified nor implemented.) | ||
- Listen for relayed connections. | ||
- Dial through the discovered relay node for any `/p2p-circuit` multiaddr. |
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.
To me, the act of 'enabling relayed connections' is a config value and not a multiaddr. Do you agree @lgierth ?
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.
@diasdavid @lgierth @whyrusleeping
I think it depends on how you look at relay. To me, relay is just another transport, hence making it behave like any other transport makes sense - here, I'm specifically talking about the dialer/listener (/stop) parts of the relay. The circuit-relay itself, can/should be controlled by config options.
Example:
Swarm: {
Addresses: [
'/p2p-circuit/<multiaddr of the Relay>' // or just plain /p2p-circuit enables circuit for listening (/stop) and dialing
]
},
Relay: {
Circuit: {
Enabled: false, // enable/disable circuit-relaying
list-peers: false // I think this will be moved to its own proto that implements `ls`
Proactive: false // should be renamed `Active`? (Active/Passive) naming
}
}
Edit:
Thinking about this a bit more, I think we should enable circuit transport by default, no need for an explicit p2p-circuit
in the swarm addrs.
relay/README.md
Outdated
- The relay node will use peer routing to find an address for QmTwo. | ||
- Also makes QmRelay available for relayed dialing, based on how listeners currently relate to dialers. | ||
- `/p2p/QmRelay/p2p-circuit` | ||
- Same as previous example, but use peer routing to find an address for QmRelay. |
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.
Just to confirm, these addresses exist to have a way to make the node always dial to the relay peer (punch out), correct?
From now on, all comments, reviews, edits and so on, should be applied directly to the document so that we keep everything in place :) |
relay/README.md
Outdated
| 260 | "passive relay has no connection to dst" | | | ||
| 261 | "active relay could not connect to dst: connection refused" | relay could not form new connection to target peer | | ||
| 262 | "could not open new stream to dst: BAD ERROR" | relay has connection to dst, but failed to open a new stream | | ||
| 270 | "<dst> does not support relay" | | |
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.
Do we really want to use 2XX+3XX for errors? Can we follow the pattern laid by HTTP:
- 1×× Informational
- 2×× Success
- 3×× Redirection
- 4×× Client Error
- 5×× Server Error
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.
👍HTTP codes are well known, which makes them more intuitive and expected.
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.
It doesnt map exactly though, i'm fine moving the 100 OK to 200 OK.
I guess we could map all the 200 errors to 400 'client' errors, and map all the 300 errors to 500 'server' errors
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.
@whyrusleeping exactly what I was hoping for ❤️
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.
After, re-reading the table... They don't really map to HTTP at all... 200s are relay codes and 300 are dst errors. So, I think 1xx, 2xx, 3xx make sense here.
relay/README.md
Outdated
| 261 | "active relay could not connect to dst: connection refused" | relay could not form new connection to target peer | | ||
| 262 | "could not open new stream to dst: BAD ERROR" | relay has connection to dst, but failed to open a new stream | | ||
| 270 | "<dst> does not support relay" | | | ||
| 320 | "src address too long" | | |
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.
From IRC:
14:13 <@daviddias> I don't understand why the 'send the src' addr keeps appearing as a thing for relay
16:05 <+dryajov> diasdavid re srs addr: I dont think we need it anymore, you are right. We can always do getPeerInfo on the circuited conn and should be able to get the src addrs. It would only make sense, if the full relay addr is sent so that the relay can be rebuilt from the dst to the src, if that ever makes sense?
16:23 <@daviddias> " It would only make sense, if the full relay addr is sent so that the relay can be rebuilt from the dst to the src, if that ever makes sense?" even in that case, we can always verify who dialed us with the getPeerInfo call
16:26 <+dryajov> True, that would be a swarm addr and should come back with the getPeerInfo. We don't need it.
relay/README.md
Outdated
|
||
This opens the room for multiple hop relay, where the first relay is encapsulated in the seconf relay multiaddr, such as: | ||
|
||
`/p2p-circuit/p2p-circuit/<first relay>/<first hop multiaddr>/<destination peer multiaddr>` |
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.
To me it makes a lot more sense to do something like - /p2p-circuit<first relay>/<first hop multiaddr>/p2p-circuit<second relay>/<second hop multiaddr>/<destination peer multiaddr>
relay/README.md
Outdated
Once it receives that, it checks if the status code is `OK`. If it is, it passes the new connection to its `NewConnHandler`. | ||
Otherwise, it returns the error message to the caller. | ||
|
||
### 'hop' protocol handler |
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.
By hop
, you mean /libp2p/circuit/relay
?
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.
No, i mean /libp2p/circuit/relay/1.0.0/hop
relay/README.md
Outdated
<uvarint 'OK'><uvarint len(msg)><string "OK"> | ||
``` | ||
|
||
And passes the relayed connection into its `NewConnHandler`. |
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.
I'm confused by this stop
handler. What case is it enabling exactly?
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.
Thats the end point in the relay flow, hop
is the relay listener, stop
listens for relayed connections coming from hop
. This is needed because you can be both a relay and listener on the same node - hence hop
and stop
sub protos.
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.
Understood.
One thing that the current spec is missing is versioning. Right now we have:
We the possibility of having a If we were to add versioning, it makes it a tad complicated because it would create a version for each of these protocols (and we already know that assuming that something will never change is an antipattern™), ending up on:
This can be ok (and maybe a question of preference), but I would rather have a single
It is not that we are trying to avoid RPC messages, we are already sending the multiaddr after first dial and we have the status codes going on. |
relay/README.md
Outdated
|
||
A `/p2p-circuit` circuit address, is formated following: | ||
|
||
`/p2p-circuit[<relay peer multiaddr>]<destination peer multiaddr>` |
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.
maybe put slashes in here?
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.
Also, after @lgierth clarifications this should be <relay peer multiaddr>/p2p-circuit/<destination peer multiaddr>
@diasdavid re versioning:
Boils down to |
what should the 'remote multiaddr' look like on a relay connection? My proposal is:
|
@whyrusleeping can you enlighten me on the |
Irc logs for context: http://lets.git.sexy/relaynotes |
@whyrusleeping can you clarify what's the
in this - |
@dryajov I mean the source multiaddr that is sent by 'A' in their initial relay request |
Another question, is it |
@whyrusleeping - both. In the first case it's peer routing, the second is over an explicit transport. Oh, and its |
I see you want to the full initial multiaddr, including any IPs, ports and so on. I question the usefulness of this, as you would only really need the peer Id (which you get from secio) and the relay addr (which you know, because you also have a conn established with it). But I guess it doesn't hurt. |
@whyrusleeping or do you mean,
? |
No, we reallllllly have to stop assuming "we will just get it from secio". Thats an assumption that hurts us I think its important to know where the connection is coming from. Though I think with the two separate protocols we could now get away with a single address, with different meaning per protocol (hop vs stop) |
The issue here is that
Am I relaying through In a diagram so i can more clearly explain myself:
|
relay/README.md
Outdated
|
||
`/p2p-circuit[<relay peer multiaddr>]<destination peer multiaddr>` | ||
|
||
This opens the room for multiple hop relay, where the first relay is encapsulated in the seconf relay multiaddr, such as: |
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.
typo: s/seconf/second/
relay/README.md
Outdated
|
||
Specify a relay: | ||
|
||
- `/p2p-circuit/p2p/QmRelay/p2p/QmTwo` |
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.
Should be:
/p2p/QmRelay/p2p-circuit/p2p/QmTwo
relay/README.md
Outdated
- Dial QmTwo, through QmRelay. | ||
- Use peer routing to find an address for QmRelay. | ||
- The relay node will also use peer routing, to find an address for QmTwo. | ||
- `/p2p-circuit/ip4/../tcp/../p2p/QmRelay/p2p/QmTwo` |
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.
Should be:
/ip4/../tcp/../p2p/QmRelay/p2p-circuit/p2p/QmTwo
relay/README.md
Outdated
- R writes `/ipfs/QmB` on `sRB` | ||
- B receives stream `sRB` and reads `/ipfs/QmB` from it. | ||
- B sees that the multiaddr it read is its own and chooses to handle this stream as an endpoint instead of attempting to relay further | ||
- TODO: step for R to send back status code to A |
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.
Thoughts on status codes:
- R doesn't send any success codes to A, only failure codes
- R would potentially also send err codes from B if the circuit is not yet established
- A would get a success or failure code from B once the circuit is established
* feat: adding err code 280 "can't relay to itlsef" * doc: reworded 280 description
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.
I've added some more comments and clarifications. Lets get this reviewed one more time.
I've reviewed:
Missing:
I'll review these last 3 in separate PRs to this one to make sure I don't merge anything to the PR without having everyone in the same page. |
Three comments, then LGTM 👍 |
Applied @lgierth review, now onto the remaining bits. |
#18 up for review |
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.
Let's merge this one, thanks @diasdavid!
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.
Lets get this merged! 👍
Not yet, #15 (comment) needs to happen. The spec is not ready. |
@diasdavid there's an inaccurate spec already merged though -- this PR is a great improvement over the existing document, and isn't technically blocked by the remaining tasks. Anyhow I added a note about this work-in-progress in #20 as an alternative. |
review Wire protocol section from the relay spec
A new chapterFollowing up the discussion on IRC (#ipfs-dev@freenode), I'll be working on finishing this spec to my best understanding and contemplating all the improvements discussed. Once this revamp is done, I'll open a new PR for formal review. |
It is here! #22 Guess what, using a protobuf simplifies so much the 'under the microscope section' :) |
In an attempt to converge all the relay spec notes and discussions, I'm listing them here, so that they can all be considered for the revamp of the relay spec. (Order represents the timeline of how theses appear, last should be considered as last 'discussed')
<src><dst><data>
multistream flow in relay #12