-
Notifications
You must be signed in to change notification settings - Fork 36
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
src/_blog: Add libp2p hole punching post #375
Conversation
Add blog post describing: - The problem of public and non-public computers in today's Internet. - The idea behind hole punching. - How libp2p does hole punching via Project Flare.
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.
Thanks for this! ❤️
Added some cosmetic references to Glossary at our docs website + suggested new paragraph at the end about client shipping behind a flag in go-ipfs 0.11.
src/_blog/libp2p-hole-punching.md
Outdated
author: Max Inden | ||
--- | ||
|
||
In case you haven't yet heard the great news, libp2p can now punch holes. |
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.
In case you haven't yet heard the great news, libp2p can now punch holes. | |
In case you haven't yet heard the great news, [libp2p](https://docs.ipfs.io/concepts/glossary#libp2p) can now _punch holes_ 🤜🕳️💢 |
LACKED EMOJI
question: what happens if hole punching fails? What are the cases where libp2p hole punching cant work? |
Good point. Added in 4f70dc1. |
Looks great @mxinden |
(We will be using the term "computer" and "node" as synonyms from now on.) | ||
|
||
## Firewalls in a nutshell | ||
|
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's worth adding a short paragraph describing the difference between stateless firewalls, which don't track connection state, and stateful firewalls.
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.
Might be a dumb question: Aren't most ISP consumer router firewalls stateful firewalls?
|
||
# Hole Punching | ||
|
||
So you can already guess what happens once both *A* and *B* dial each other simultaneously, … a **hole punch**. Let's play through this one more time, using the sequence diagram on generic hole punching from the beginning of this blog post: |
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 call out that they need to swap their source and destination ports, respectively, so that the state tables match up.
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 am not sure I follow. Could you expand on this @squeed?
A node A can discover its externally facing listen addresses via other nodes in the network. When connecting to another node B, B tells A what address it perceives A under.
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.
This is a great starting point, thank you @mxinden for putting in the work.
I found a whole bunch of nits from my side (see below)...
src/_blog/libp2p-hole-punching.md
Outdated
|
||
So you can already guess what happens once both *A* and *B* dial each other simultaneously, … a **hole punch**. Let's play through this one more time, using the sequence diagram on generic hole punching from the beginning of this blog post: | ||
|
||
> 1. *A*'s packet would pass through router *A* and thus add a 5-tuple to router *A*'s state table. Same on the other side, where the packet send by *B* would trigger a 5-tuple being added to *B*'s router's state table. Packet *A* and packet *B* "punch holes" into their router's firewalls. |
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.
This is exactly the same as above. We probably don't need this, or at least we can abbreviate it.
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.
Is that not obvious by the fact that it is quoted? I kind of like that the blog post is cyclic, i.e. ends with the initially proposed solution.
src/_blog/libp2p-hole-punching.md
Outdated
|
||
### 1.1 Determine whether one is dialable (AutoNAT) | ||
|
||
In step 1 of phase 1 a node determines whether it is dialable, in other words it determines whether computers outside of its own network can connect to it. The main protocol involved here is the [libp2p *AutoNAT* protocol](https://github.com/libp2p/specs/blob/master/autonat/README.md). (Worth drawing the connection to the corresponding ICE protocol [STUN](https://datatracker.ietf.org/doc/html/rfc5389) 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.
8489 obsoleted 5389.
Also, isn't the better equivalent for STUN Identify, not AutoNAT?
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.
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.
This is great. It was fun to read. Thanks for writing it up. A couple of things:
Diagrams
- I saw the discussion about using the design shop. I'm not against it but I don't have a sense of how much bang for the buck we get. I do wonder though if there is a "stylesheet" that can be applied that takes the edge off here. I don't know how big their queue is and how long back and forth are, but I don't want to add friction unnecessarily. We certainly need them for artwork, but engineers are used to seeing/reading diagrams. If we can just have our UML diagrams look prettier, maybe that is a happy medium?
- I was at first worried that we didn't have the raw UML, but I see it's embedded in the SVG. I want to make sure that if someone needs to update or use these diagrams that they know there is UML they can start from. Is it commonly known that the UML is embedded in the SVG. If so, great. If not, maybe we add a note somewhere/
High level blog post thoughts
Things I would want to know after reading this:
- What can go wrong? I assume this is where the discussion about timing/latency becomes relevant.
- How effective is this? I know we don't have that data yet.
Maybe we commit to saying the items above will be discussed in a future blog entry (or maybe we wait until we have written a followup and then can update this original one).
Tone
The tone is more of of one giving a fun/upbeat presentation. I'm not calibrated on the historical tone of the technical blog entries. I assume this is in line. I'm just double checking that it's a conscious choice, and if it is, the suggestions/updates lean into it with emojis, etc. make sense.
Thanks again @mxinden !
|
||
![img](../assets/libp2p-hole-punching-dcutr.svg) | ||
|
||
Now, if you do the math, *A* starts after half the round trip time between *A* and *B* via the relay, and *B* starts once it receives the *Sync*. This should roughly account to the same point in time. |
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 know we said we're not getting into latency in this blog post.
The thing I was curious about is why we wait for half the round trip time. Would it make sense to explain this more?
Assuming the latency between A-relay-B is close to A-B, why not instead wait for 75% of the A-relay-B round trip time before sending the A->B dial. That would increase the amount of time from when the B->A dial has been sent before the A->B dial comes in.
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.
Assuming the latency between A-relay-B is close to A-B, why not instead wait for 75% of the A-relay-B round trip time before sending the A->B dial. That would increase the amount of time from when the B->A dial has been sent before the A->B dial comes in.
While increasing the time from "when the B->A dial has been sent before the A->B dial comes in", it decreases the time from when the A->B dial has been sent before the B->A dial comes in.
Both timings need to be right, i.e. both packet from A->B and B->A need to find a hole in the firewall of the other side once they arrive. Improving the timing for one happens at the expense of the other.
Does that make sense @BigLep? Any suggestion on how to make this more clear? In other words any suggestions on how to avoid the confusion?
Co-authored-by: Steve Loeppky <stvn@loeppky.com>
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.
Thanks @BigLep! Did a first pass. Will address the remaining comments in a bit.
Co-authored-by: Steve Loeppky <stvn@loeppky.com>
As far as I can tell all review comments are either addressed directly or don't need to block the publishing of the post. In other words, this post is ready to be published. @emilymvaughan when would be a good time to publish this post? |
Hi @mxinden ! I am happy for this post to go live today. In that case, can you please adjust the date on the post? |
Done. @emilymvaughan can you take care of the social media advertisement of the post as well? |
Yes, of course!! Will merge now. |
Thanks everyone for the help! |
Add blog post describing:
Depends on: