How Tailcat Handles NAT Traversal: DERP Relays, Magicsock, and Direct WireGuard Upgrades

Tailcat performs NAT traversal by bootstrapping connections through DERP relays, discovering public UDP endpoints via magicsock, and upgrading to direct peer-to-peer WireGuard tunnels once a viable path is found.

Tailcat, the open-source reverse proxy built on Tailscale's networking stack, implements a control-plane-free NAT traversal strategy that mirrors the standard Tailscale mesh. By leveraging the same data-plane components used in production WireGuard networks, Tailcat establishes direct connections between nodes without requiring inbound firewall rules or coordination servers.

Bootstrapping Through DERP Relays

When two Tailcat nodes initiate communication, they begin by connecting to a DERP (Distributed Edge Relay) server. This relay forwards UDP packets when no direct path exists through NATs or firewalls. According to the tailscale/tailcat source code, the DERP region information is embedded directly in the connection token (the ConnBlob), allowing clients to reach the relay without performing any extra network lookups. This design ensures that nodes can always communicate, even when symmetric NATs block direct inbound connections. The bootstrap logic resides in tailcat.go between lines 5 and 22.

Magicsock Endpoint Discovery

Each Tailcat node runs a magicsock instance via tsdial.Dialer to manage UDP sockets. Magicsock learns the node's public UDP endpoints through STUN queries and local-interface probing. When the set of available endpoints changes—such as when a device switches networks—the locoBackend.onEngineStatus callback stores the new list and triggers an advertisement to all peers. This mechanism, implemented at lines 84-99 of tailcat.go, ensures that every node maintains an up-to-date view of its own network topology.

The CallMeMaybe Handshake Protocol

After the initial WireGuard handshake—internally referred to as the meow/meowed exchange—Tailcat initiates endpoint advertisement. The node sends a signed CallMeMaybe message over the DERP relay containing its current UDP endpoints. This critical step occurs in locoBackend.advertiseEndpoints (lines 1104-1120 of tailcat.go). The recipient's magicsock receives this message and immediately probes the advertised addresses, testing for bidirectional UDP connectivity without requiring the sender to predict which path will succeed.

Routing and Direct Path Establishment

Once magicsock discovers a viable direct path, the WireGuard engine reconfigures to use it. The engine relies on two key callback mechanisms defined in tailcat.go (lines 1038-1053): SetPeerByIPPacketFunc and SetPeerConfigFunc. These functions utilize the discovered peer maps—peerByIP and peerAllowedIPs—to route traffic directly to the remote node. When a direct UDP path is confirmed, the tunnel bypasses the DERP relay entirely, reducing latency and increasing throughput.

Automatic Connection Upgrades

Tailcat continuously attempts to improve connection quality. As noted in the source at lines 1693-1700, repeated ping exchanges (the meow/meowed protocol) serve as keepalives while simultaneously probing for better paths. When magicsock identifies a superior direct route, the WireGuard tunnel rebuilds to use it instantly, while maintaining the DERP connection as a fallback. This ensures resilience: if the direct path fails due to network changes, traffic immediately flows back through the relay without dropping the connection.

Practical Implementation

While the NAT traversal complexity remains hidden from application code, the following Go implementation demonstrates how the high-level API encapsulates these mechanisms:

// Server side – start a Tailcat server that will accept clients.
srv := &tailcat.Server{
    Logf:   log.Printf, // optional custom logger
    // Region can be omitted – the server will auto‑pick the nearest DERP.
}
if err := srv.Start(); err != nil { log.Fatalf("start: %v", err) }
defer srv.Close()

// Export the connection token (ConnBlob) to give to clients.
token := srv.ConnBlob()
fmt.Println("Connect token:", token)

// Client side – connect to the server using the token.
cli := tailcat.NewClient(token)
if err := cli.Dial(ctx, "example.com:80"); err != nil {
    log.Fatalf("dial: %v", err)
}
defer cli.Close()

Under the hood, the client executes the full NAT traversal sequence: parsing the ConnBlob to identify the DERP region, contacting the relay, exchanging meow/meowed packets to establish the WireGuard session, and advertising endpoints via advertiseEndpoints. Once the server responds with its own endpoints and magicsock validates the direct path, the connection upgrades automatically.

Summary

  • DERP bootstrapping: Connections start through embedded relay servers to bypass restrictive NATs, using the ConnBlob token to locate the nearest region without DNS lookups.
  • STUN-based discovery: Magicsock determines public UDP endpoints and monitors for network changes via onEngineStatus.
  • CallMeMaybe protocol: Nodes exchange signed endpoint advertisements over DERP after the WireGuard handshake, enabling symmetric NAT traversal.
  • Zero-configuration routing: Engine callbacks SetPeerByIPPacketFunc and peer maps handle traffic routing once direct paths are established.
  • Seamless upgrades: Continuous ping exchanges probe for better paths, automatically migrating from relay to direct UDP while maintaining DERP as fallback.

Frequently Asked Questions

How does Tailcat differ from standard Tailscale in NAT traversal?

Tailcat uses the exact same data-plane components as Tailscale—DERP, magicsock, and WireGuard—but operates without a control plane or user accounts. It embeds DERP coordinates directly in connection tokens, allowing immediate peer-to-peer establishment without querying a coordination server.

What happens if a direct UDP path cannot be established?

If symmetric NATs or strict firewalls prevent direct connectivity, Tailcat continues using the DERP relay indefinitely. The WireGuard tunnel remains functional with encrypted traffic flowing through the relay server, ensuring connectivity even in hostile network environments.

Does Tailcat require manual port forwarding or firewall configuration?

No. The NAT traversal mechanism functions automatically through outbound UDP connections to DERP servers and STUN endpoints. The CallMeMaybe protocol handles the complexity of informing peers about available paths without requiring inbound firewall rules.

How quickly does Tailcat upgrade from relay to direct connections?

The upgrade occurs as soon as magicsock validates bidirectional UDP connectivity, typically within seconds of the initial handshake. The continuous ping exchange (meow/meowed) ensures that if a direct path becomes available later—such as when a laptop moves to a less restrictive network—the connection upgrades automatically without reconnection.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →