# NAT Traversal

ant-quic implements QUIC-native NAT traversal without requiring STUN, TURN, or ICE protocols. The implementation follows [draft-seemann-quic-nat-traversal-02](../../rfcs/draft-seemann-quic-nat-traversal-02.txt).

## Overview

NAT traversal in ant-quic works through:
1. **Address Discovery**: Learn your external address from peers
2. **Candidate Exchange**: Share candidate addresses with target peer
3. **Coordinated Hole Punching**: Simultaneous packet exchange to open NAT mappings
4. **Direct Connection**: Establish QUIC connection through the punched hole

## Why QUIC-Native?

Traditional NAT traversal uses separate protocols (STUN/TURN/ICE). ant-quic integrates NAT traversal directly into QUIC:

| Traditional | QUIC-Native |
|-------------|-------------|
| STUN servers for address discovery | OBSERVED_ADDRESS frames from peers |
| TURN servers for relay | Any peer can relay |
| ICE for coordination | PUNCH_ME_NOW frames for coordination |
| Separate UDP sockets | Same QUIC connection |

Benefits:
- **No external infrastructure**: Any peer can help with discovery
- **Faster**: Uses existing QUIC connections
- **Simpler**: One protocol instead of three
- **Secure**: All traffic encrypted with PQC

## Symmetric P2P Model

In ant-quic v0.13.0+, **all nodes participate equally** in NAT traversal. Any node with a public IP address can serve as the coordination peer that helps two NAT'd nodes connect.

## Address Discovery

When you connect to a peer, they observe your source address and send it back using the OBSERVED_ADDRESS frame (0x9f81a6 for IPv4, 0x9f81a7 for IPv6). This replaces the need for STUN servers.

### OBSERVED_ADDRESS Frame Format

```
Frame Type: 0x9f81a6 (IPv4) or 0x9f81a7 (IPv6)
Payload: IP Address (4 or 16 bytes) + Port (2 bytes)
```

## Hole Punching Protocol

### Step 1: Candidate Exchange

Nodes share their candidate addresses via ADD_ADDRESS frames (0x3d7e90-91):

```
ADD_ADDRESS Frame:
- Address ID (variable)
- IP Version (4 or 6)
- IP Address (4 or 16 bytes)
- Port (2 bytes)
- Priority (variable)
```

### Step 2: Coordinated Punching

The PUNCH_ME_NOW frame (0x3d7e92-93) coordinates timing:

```
PUNCH_ME_NOW Frame:
- Peer Address ID
- Path ID
- Timestamp
```

Both peers send packets simultaneously to punch through their respective NATs.

### Step 3: Connection Establishment

Once the hole is punched, QUIC connection establishment proceeds normally using the newly discovered direct path.

## NAT Types Supported

| NAT Type | Success Rate |
|----------|--------------|
| Full Cone | 100% |
| Address Restricted | 95%+ |
| Port Restricted | 90%+ |
| Symmetric | 70%+ |
| Carrier-Grade NAT (CGNAT) | 60%+ |

## Configuration

NAT traversal is enabled by default. Configuration options:

```rust
use ant_quic::P2pConfig;

let config = P2pConfig::builder()
    .known_peers(vec!["peer1.example.com:9000".parse()?])
    .build()?;
```

## Monitoring

Check NAT traversal statistics via the metrics system:

```rust
let stats = endpoint.get_nat_traversal_stats();
println!("Direct connections: {}", stats.direct_connections);
println!("NAT traversals: {}", stats.successful_traversals);
println!("Success rate: {:.1}%", stats.success_rate() * 100.0);
```

## Troubleshooting

### No External Address Discovered

- Ensure at least one peer with a public IP is reachable
- Check firewall rules allow UDP traffic
- Verify the peer is correctly observing and reporting addresses

### Hole Punch Failures

- Symmetric NATs may require multiple attempts
- Try increasing the punch attempt timeout
- Consider using a relay as fallback

### Connection Timeouts

- Check both peers have correctly exchanged candidates
- Verify coordination timing between peers
- Enable debug logging for detailed diagnostics

## See Also

- [QUIC NAT Traversal Draft](../../rfcs/draft-seemann-quic-nat-traversal-02.txt)
- [Address Discovery Draft](../../rfcs/draft-ietf-quic-address-discovery-00.txt)
- [Post-Quantum Cryptography](./pqc.md)
