Skip to content
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

Merged
merged 45 commits into from
Mar 3, 2022

Conversation

mxinden
Copy link
Contributor

@mxinden mxinden commented Jan 23, 2022

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.

Depends on:

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.
Copy link
Member

@lidel lidel left a 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.

author: Max Inden
---

In case you haven't yet heard the great news, libp2p can now punch holes.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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 :trollface:

src/_blog/libp2p-hole-punching.md Outdated Show resolved Hide resolved
src/_blog/libp2p-hole-punching.md Outdated Show resolved Hide resolved
src/_blog/libp2p-hole-punching.md Outdated Show resolved Hide resolved
src/_blog/libp2p-hole-punching.md Outdated Show resolved Hide resolved
src/_blog/libp2p-hole-punching.md Outdated Show resolved Hide resolved
src/_blog/libp2p-hole-punching.md Outdated Show resolved Hide resolved
src/_blog/libp2p-hole-punching.md Outdated Show resolved Hide resolved
src/_blog/libp2p-hole-punching.md Show resolved Hide resolved
src/_blog/libp2p-hole-punching.md Outdated Show resolved Hide resolved
@momack2
Copy link
Contributor

momack2 commented Jan 26, 2022

question: what happens if hole punching fails? What are the cases where libp2p hole punching cant work?

@mxinden
Copy link
Contributor Author

mxinden commented Jan 27, 2022

question: what happens if hole punching fails? What are the cases where libp2p hole punching cant work?

Good point. Added in 4f70dc1.

@BlocksOnAChain
Copy link

Looks great @mxinden

(We will be using the term "computer" and "node" as synonyms from now on.)

## Firewalls in a nutshell

Copy link

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.

Copy link
Contributor Author

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:
Copy link

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.

Copy link
Contributor Author

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.

Copy link
Member

@marten-seemann marten-seemann left a 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 Show resolved Hide resolved
src/_blog/libp2p-hole-punching.md Outdated Show resolved Hide resolved
src/_blog/libp2p-hole-punching.md Outdated Show resolved Hide resolved
src/_blog/libp2p-hole-punching.md Outdated Show resolved Hide resolved
src/_blog/libp2p-hole-punching.md Outdated Show resolved Hide resolved
src/_blog/libp2p-hole-punching.md Outdated Show resolved Hide resolved

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.
Copy link
Member

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.

Copy link
Contributor Author

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 Show resolved Hide resolved
src/_blog/libp2p-hole-punching.md Outdated Show resolved Hide resolved
src/_blog/libp2p-hole-punching.md Outdated Show resolved Hide resolved

### 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.)
Copy link
Member

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?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

8489 obsoleted 5389.

🙏 fixed in dce9fbc

Also, isn't the better equivalent for STUN Identify, not AutoNAT?

I would argue both, no?

  • identify to learn ones listening address
  • autonat to check whether that listening address is dialable

dce9fbc lists both.

Copy link
Contributor

@BigLep BigLep left a 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

  1. 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?
  2. 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:

  1. What can go wrong? I assume this is where the discussion about timing/latency becomes relevant.
  2. 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 !

src/_blog/libp2p-hole-punching.md Outdated Show resolved Hide resolved
src/_blog/libp2p-hole-punching.md Outdated Show resolved Hide resolved
src/_blog/libp2p-hole-punching.md Outdated Show resolved Hide resolved
src/_blog/libp2p-hole-punching.md Outdated Show resolved Hide resolved
src/_blog/libp2p-hole-punching.md Outdated Show resolved Hide resolved

![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.
Copy link
Contributor

@BigLep BigLep Feb 22, 2022

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.

Copy link
Contributor Author

@mxinden mxinden Feb 24, 2022

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?

src/assets/libp2p-hole-punching-network.svg Outdated Show resolved Hide resolved
src/assets/libp2p-hole-punching-autonat.svg Outdated Show resolved Hide resolved
src/assets/libp2p-hole-punching-dcutr.svg Outdated Show resolved Hide resolved
src/assets/libp2p-hole-punching-relay-v2-connect.svg Outdated Show resolved Hide resolved
Co-authored-by: Steve Loeppky <stvn@loeppky.com>
Copy link
Contributor Author

@mxinden mxinden left a 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.

src/assets/libp2p-hole-punching-dcutr.svg Outdated Show resolved Hide resolved
src/assets/libp2p-hole-punching-network.svg Outdated Show resolved Hide resolved
src/assets/libp2p-hole-punching-relay-v2-connect.svg Outdated Show resolved Hide resolved
src/assets/libp2p-hole-punching-autonat.svg Outdated Show resolved Hide resolved
src/_blog/libp2p-hole-punching.md Outdated Show resolved Hide resolved
src/_blog/libp2p-hole-punching.md Outdated Show resolved Hide resolved
@mxinden mxinden marked this pull request as ready for review February 25, 2022 14:22
Co-authored-by: Steve Loeppky <stvn@loeppky.com>
src/_blog/libp2p-hole-punching.md Outdated Show resolved Hide resolved
src/_blog/libp2p-hole-punching.md Outdated Show resolved Hide resolved
@mxinden
Copy link
Contributor Author

mxinden commented Mar 3, 2022

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?

@emilymvaughan
Copy link
Collaborator

Hi @mxinden ! I am happy for this post to go live today. In that case, can you please adjust the date on the post?

@mxinden
Copy link
Contributor Author

mxinden commented Mar 3, 2022

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?

@emilymvaughan
Copy link
Collaborator

emilymvaughan commented Mar 3, 2022

Yes, of course!! Will merge now.

@emilymvaughan emilymvaughan merged commit 784e036 into ipfs:main Mar 3, 2022
@mxinden
Copy link
Contributor Author

mxinden commented Mar 3, 2022

Thanks everyone for the help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants