good prior reading: https://tailscale.com/blog/how-nat-traversal-works/

DERP Regions documentation:

DERP Protocol documentation:

Main goals

Hole Punching Summary

Our plan was to take the open source protocols from Tailscale, but implement them in Rust over QUIC rather than WireGuard. Specifically, taking Tailscale’s philosophy of having all of the hole punching happen in a “MagicSocket” and using the DERP (”Designated Encrypted Relay for Packets”) protocol for packet relays, and the Disco (”discovery”) protocol for hole punching.

However, we additionally need the ability to dial using PublicKey, which makes for a tricky dance with the quinn::Endpoint and MagicSock, since there is no concept of dialing via a public key in QUIC.

MagicSock

The API is centered around the “MagicSocket” or MagicSock. Iroh creates a MagicSock and uses that socket as an AsycnUdpSocket in a quinn::Endpoint. All the connection/hole punching work happens inside of the MagicSock. As far as QUIC is concerned, all of the packets going in and out of the quinn::Endpoint are being sent over UDP.

In reality, the Magicsock binds an IPv4 and IPv6 UDP socket. It also spins up a DERP Client for each DERP server we are configured to connect with over HTTP/HTTPS. You need to be connected to at least one Derper (DERP + STUN server) in order to do any hole punching.

To dial a peer, you must first add the peer to MagicSock explicitly via its public key (and any known addresses) and get a “mapped address” in return, which is an IPv6 Unique Local Address with a fixed Global ID and Subnet ID to easily identify it as such. This mapped address is what you pass to the quinn::Endpoint in order to dial that per. This ensures we are able to dial via a public key.

Each time you send packets to a particular peer, the MagicSock will request the best_addr from its internal peer address book. This means the address and socket on which we send the latest packet may be different from the one we sent previously.