While debugging an issue with a user, I found myself describing how reflexive public IP address discovery works, the role of AutoNAT, and when AutoRelay kicks in.
Here are my notes for the benefit of the community:
- As we connect to peers in the network, we learn the addresses of us they observe via the Identify protocol. This is basically the source ip:port tuple of the socket.
- We use
SO_REUSEPORTsocket options when dialing and listening, so the address we dial peers from is the same address they can use to dial us back, as long as we’re not behind a NAT.
- In other words, we don’t dial from ephemeral (random) ports locally. But if we’re behind a NAT, the peer might see the source port changing as the NAT updates mappings.
- We use
- We track the observed addresses peers report to us reflexively.
- We “activate” an address when we observe it 4 times from different peers, and we expire addresses we haven’t seen in a while.
- The component that does this in go-libp2p is the
- This logic is a bit arbitrary and needs to be made flexible/pluggable.
- AutoNAT has two components: the client and the service.
- AutoNAT is a reflexive dialback gadget. AutoNAT clients request dial backs from peers running the AutoNAT service, to confirm they are indeed dialable on addresses they suspect are valid inbound addresses (as per the logic in point 2).
- AutoRelay needs AutoNAT to know when to kick in. AutoRelay peers are all AutoNAT clients. They are capable of requesting dial backs to determine their NAT status (public, behind a NAT, unknown).
- Bootstrappers, relay nodes, etc. offer the AutoNAT service.
- When AutoNAT clients connect to any peer in the network, they try to open a stream for AutoNAT.
- If the other party NACKs the stream, they are not an AutoNAT service and we cannot request a dialback from them.
- If the other party ACKs the stream, they are an AutoNAT service and we request a dialback from them.
- After 3 peers (confidence threshold) have confirmed they can dial back to us on our observed addresses, AutoNAT makes the determination that we are publicly diallable, and we advertise our observed addresses to other peers.
- The AutoRelay subsystem deactivates.
- If we do not reach this confidence threshold, AutoNAT assumes we are running behind a NAT and are not diallable via a pinhole.
- The AutoRelay subsystem activates, finds relays in the network, connects to them, and advertises our relay addresses to all connected peers.
Hope this summary was useful.