Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 57 additions & 6 deletions content/concepts/nat/autonat.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ If most of these dial attempts are successful, the node can be reasonably sure
that it is not behind a NAT. On the other hand, if most of these dial attempts fail,
it strongly indicates that a NAT is blocking incoming connections.

{{< alert icon="" context="">}}
Currently, AutoNAT cannot test individual addresses,
but a [proposal](https://github.com/libp2p/specs/issues/503) for AutoNAT v2 aims to
add this capability.
{{< /alert >}}
## AutoNAT v1 vs v2

libp2p supports two versions of the AutoNAT protocol:

### AutoNAT v1

The AutoNAT protocol uses the protocol ID `/libp2p/autonat/1.0.0` and involves
AutoNAT v1 uses the protocol ID `/libp2p/autonat/1.0.0` and involves
the exchange of `Dial` and `DialResponse` messages.

To initiate the protocol, a node sends a `Dial` message to another peer containing
Expand All @@ -67,6 +67,57 @@ whether or not it is behind a NAT.
> an error, the node is likely behind a NAT and may need to use a
> [relay server]({{< relref "/concepts/nat/dcutr.md" >}}) to communicate with other nodes in the network.

AutoNAT v1 determines reachability at the node level and it cannot distinguish whether
specific addresses (e.g., IPv4 vs IPv6) are reachable independently.

### AutoNAT v2

AutoNAT v2 extends the original protocol with the ability to determine reachability
for **individual addresses**. This enables nodes to:

- Check reachability separately for IPv4, IPv6, and WebTransport/WebRTC addresses
- Know exactly which addresses are publicly accessible
- Make smarter decisions about which addresses to advertise

AutoNAT v2 uses the protocol ID `/libp2p/autonat/2.0.0`.

#### Querying confirmed addresses

In go-libp2p, you can query addresses that have been confirmed as reachable using
the `ConfirmedAddrs()` method:

```go
// Get addresses confirmed reachable by AutoNAT v2
confirmedAddrs := host.ConfirmedAddrs()
for _, addr := range confirmedAddrs {
fmt.Println("Confirmed reachable:", addr)
}
```

#### Subscribing to reachability changes

You can subscribe to the `EvtHostReachableAddrsChanged` event to be notified when
the set of reachable addresses changes:

```go
sub, err := host.EventBus().Subscribe(new(event.EvtHostReachableAddrsChanged))
if err != nil {
log.Fatal(err)
}
defer sub.Close()

for evt := range sub.Out() {
e := evt.(event.EvtHostReachableAddrsChanged)
fmt.Println("Reachable addresses changed:", e.Addrs)
}
```

{{< alert icon="" context="info">}}
AutoNAT v2 is available in go-libp2p v0.42.0 and later.
{{< /alert >}}

## Security considerations

{{< alert icon="" context="caution">}}
To prevent
[certain types of attacks](https://www.rfc-editor.org/rfc/rfc3489#section-12.1.1),
Expand Down
3 changes: 2 additions & 1 deletion content/concepts/nat/hole-punching.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ a hole punching phase.
- `Other_Peers` attempt to dial each of `B`'s addresses and report the
outcome back to `B`.
- Based on the reports, `B` can gauge whether it is publicly dialable and
determine if hole punching is needed.
determine if hole punching is needed. With AutoNAT v2, `B` can determine
reachability for each address individually (e.g., IPv4 vs IPv6).

<!-- to add routing reference when available -->
<!-- to add autorelay reference when available -->
Expand Down