Hole punching in dockerized service using js-libp2p

Hello everyone,

I’ve invested considerable time attempting to implement hole punching with js-libp2p. However, progress has been elusive thus far, and I find myself with several questions. Here are some of the most prominent ones:

  1. In a network featuring only one relay and two nodes behind NAT, is hole punching feasible? Are there any limitations on the number of nodes? (For instance, I noticed that autonat requires at least 4 confirmations from other nodes to validate an observed address.)
  2. Can hole punching be achieved with containerized nodes? I’ve come across repositories like mysteriumnetwork, seemingly running in Docker and successfully implementing hole punching. On the contrary, Docker networks, particularly the bridge driver, appear to mimic a symmetric NAT, hindering hole punching.
  3. Are listen addresses a prerequisite for nodes to engage in hole punching, or is a connection to the relay sufficient to initiate hole punching?
  4. Are there any documented instances of successful hole punching using js-libp2p in a real-world project or repository?

Your insights and guidance on these matters would be immensely appreciated. I can share some codes too, if that helps.

Some more investigations on a non-dockerized environment:

I tried the rust version of libp2p which has sample relay and dcutr examples. The scenario is as follows:

  1. Listener, running on my laptop, is connected to access point L.
  2. Dialer, running on another laptop, is connected to a different access point (say D).
  3. Relay is running on a server with public address.

I checked the type of both access point NATs using stunclient, which shows “Nat behavior: Endpoint Independent Mapping”.

Then I run the simple hole punching scenario, but it doesn’t work and direction connection cannot be established with various errors related to connections (e.g. timeout, connection refused, etc.)

Hi @mkermani144 ,

Thanks for your post. I think you’ll get a better response if you post this question on the technical js-libp2p forum on Github here: libp2p/js-libp2p · Discussions · GitHub

Be sure to @ tag sukunrt (Sukun) · GitHub, he’s our current hole punching guru working on AutoNat v2

@dhuseby
Thanks for letting me know. I tried a dockerized hole punching scenario with rust-libp2p on two server instances without public ip, and it worked. I prefer to first ensure the js-libp2p works the same, and then follow-up on my questions (if any). For now, I’m pretty sure my ISP uses multiple levels of NAT, which makes hole punching impossible.

You’re welcome and I hope you figure it out. Relaying packets through a public libp2p peer should be possible regardless of the number of NAT layers since both peers connect outwards to the public peer.

Thanks, I had some conversations in the GitHub discussion and am experimenting some possible solutions.
The relay solution works, but the problem is that for a large network with considerable traffic, relay nodes become single points of failure.

1 Like