-
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
add a spec for autonat #362
Conversation
dial all of them in parallel. The peer MAY use a different IP and peer ID than | ||
it uses for its regular libp2p connection to perform these dial backs. |
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.
If I understand correctly the fact that a server might use a different peer ID is due to an implementation detail in the Golang implementation. Given that AutoNAT is already widely deployed we won't be able to change that in this iteration. Still, would you mind documenting this, to ease discussions on this in future versions?
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 not sure we'd even want to change this in a future iteration, but I'm ok with documenting the reasoning here. Can you suggest some text?
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 not sure we'd even want to change this in a future iteration
I might be missing something here. What is the benefit of this amendment other than not having to fix the shortcomings within a single implementation?
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 disagree that this is a shortcoming to begin with.
All we're interested in is if an address is dialable - who dials it (and from what address) is completely irrelevant.
Note that in the current iteration of this protocol, a node doesn't check if | ||
a peer's report of a successful dial is accurate. This might be solved in a | ||
future iteration of this protocol, see | ||
https://github.com/libp2p/go-libp2p-autonat/issues/10 for a detailed discussion. |
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.
🙏
Co-authored-by: Max Inden <mail@max-inden.de>
On address prioritization I read quite a bunch of NAT traversal related RFCs (4787, 5128, 4614, 5382, 7604, 7857, 5389, 8445) At the current state of Project Flare, I think the only thing useful would be RFC8445, more specifically section 5 on (address) candidate selection. https://datatracker.ietf.org/doc/html/rfc8445#section-5 They differentiate in 4 candidate types, depending on the mechanism the address was discovered through:
Section 5.1.2.1 then follows with a formula to prioritize among the many addresses depending on their type. Would (a) the candidate type differentiation and (b) the proposed prioritization formula be something worth adopting in this specification or our implementations? What do you think @marten-seemann? |
Document that peers MUST NOT dial addresses that are not based on the IP addresses the requesting node is observed as. Corresponding logic in Golang implementation: https://github.com/libp2p/go-libp2p-autonat/blob/1247ac6d9fa798e7032127878a6f3d0b9eb487c6/svc.go#L133-L147
|
||
The AutoNAT Protocol uses the Protocol ID `/libp2p/autonat/1.0.0`. The node | ||
wishing to determine its NAT status opens a stream using this protocol ID, and | ||
then sends a `Dial` message. The `Dial` message contains a list of multiaddresses. |
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.
The PeerInfo
that is send in the Dial
message also (may?) contain the target's peer ID. Should it be enforced that this Peer ID matches the sender's Peer ID?
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 would expect addresses in PeerInfo::addrs
not to contain peer IDs (/p2p/QmXXX
), given that the peer ID is already carried in PeerInfo::id
.
That said, I would suggest to take the liberal approach of allowing addresses in PeerInfo::addrs
to contain peer IDs anyways. Though in that case, I do agree that implementations should enforce the peer IDs to match.
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 would expect addresses in PeerInfo::addrs not to contain peer IDs (/p2p/QmXXX), given that the peer ID is already carried in PeerInfo::id.
Sorry I probably placed my comment wrong.
I was referring to PeerInfo::id
, not PeerInfo::addrs
.
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.
Ah, sorry, my bad.
The Golang implementation does the validation you suggest, namely validate that the peer ID in PeerInfo
matches the remote's peer ID.
To be honest, I don't know why we send the peer ID in the first place. Maybe @marten-seemann knows more.
One case just popped up in my mind where I am not sure how to handle it for rust-autonat: |
In my eyes one should be able to send
I am not sure I follow. Both as a dialer and as a listener of a connection one knows the address of the remote peer. One might not observe the right port, though the AutoNAT protocol does not discriminate on the port, only on the IP. Am I missing something?
Off the top of my head, I don't think the overhead of establishing a new relayed connection is worth it, i.e. in case B can not be dialed directly, but only via a relay, I don't think they are a valid AutoNAT partner. I do think it is worth trying on an already established relayed connection. |
Sorry. This obviously conflicts with 048bdbf. My bad. One should not send nor accept |
Maybe I understand the relay protocol wrong.
Is this the case, or does the remote observe them at a relayed address in both cases? |
Correct. The remote would observe
In the case where the remote is public and In the case where the remote is not publicly reachable and is as well listening via some relay,
https://github.com/libp2p/specs/blob/master/relay/circuit-v2.md#stop-protocol The remote could infer the address of Does the above answer the question? Unfortunately this is not clearly defined. Thanks for raising it. |
* autonat/README: Add table-of-content * autonat/README: Describe stream lifecycle * autonat/README: Wrap lines * autonat/README.md: Remove stream closing item
In order to uphold the defense mechanism introduced in 048bdbf one should not accept dial requests via relayed connections.
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 would argue that this document is helpful as is and thus worth merging. Any objections @marten-seemann @elenaf9?
Discussed out of band that this is ready to merge. |
No description provided.