How Tailcat Enables Peer-to-Peer Networking Without a Control Plane

Tailcat leverages existing Tailscale subsystems—DERP relays for initial handshake, Meow Ping packets for peer discovery, and WireGuard for encrypted tunnels—to establish direct peer-to-peer connections without requiring a central control plane or coordination server.

Tailcat is an experimental project within the tailscale/tailcat repository that demonstrates how to build a fully decentralized mesh network using components already present in every Tailscale node. By repurposing the DERP (Datacenter Endpoint Relay Protocol) infrastructure for bootstrapping and implementing a lightweight "Meow" handshake protocol, Tailcat eliminates the need for a traditional control plane while maintaining the security and NAT-traversal capabilities of WireGuard.

The Architecture of Control-Plane-Free Networking

Traditional mesh VPNs rely on a centralized control plane to distribute public keys, manage ACLs, and coordinate peer discovery. Tailcat inverts this model by embedding the discovery and authorization logic directly into the data plane. Every node runs a complete stack consisting of a DERP client, a custom packet parser for peer admission, and a user-space WireGuard engine.

The architecture rests on four pillars: DERP as a rendezvous relay, the Meow Ping protocol for authenticated introduction, lazy configuration of the WireGuard engine, and Disco-based direct path discovery.

DERP as the Initial Relay Layer

Tailcat repurposes DERP—ordinarily used as a fallback relay when UDP fails—as the bootstrap mechanism for new peer relationships. Rather than requiring a separate coordination service, nodes communicate through existing DERP regions already deployed in the Tailscale network.

The onDERPRecv Callback

When a Tailcat server initializes in tailcat.go, it registers a callback function named onDERPRecv that inspects every incoming DERP packet for a magic prefix. As implemented in lines 613–630 of tailcat.go, this callback checks for the meowMagic string at the start of each packet:

// Simplified logic from tailcat.go#L613-L630
func (s *Server) onDERPRecv(from key.NodePublic, pkt []byte) bool {
    if !IsMeowPacket(pkt) {
        return false // Not a Meow packet, pass through
    }
    // Parse the Meow Ping and extract keys
    nodePub, discoPub, err := ParseMeowPing(pkt)
    if err != nil {
        return false
    }
    // Process the peer admission...
    s.onMeow(from, nodePub, discoPub)
    return true
}

This callback operates entirely within the data plane, requiring no external API calls or database lookups beyond an optional AllowedClients map.

Packet Validation via Magic Prefix

The server distinguishes Tailcat control traffic from regular DERP data by scanning for the "meow" magic prefix. Valid packets trigger the peer admission logic, while invalid packets continue through normal processing. This filtering happens before any WireGuard handshake occurs, ensuring that only authorized nodes can trigger configuration changes.

Meow Ping Protocol for Peer Discovery

The Meow protocol defines a custom DERP payload format that carries cryptographic identities without relying on a central directory. This protocol handles the entire introduction sequence between two previously unknown peers.

Encoding and Parsing Control Packets

The disco.go file defines the wire format for these control messages. Lines 30–65 implement EncodeMeowPing, which constructs the introduction packet containing the client's node public key and derived Disco key:

// From disco.go#L30-L65
func EncodeMeowPing(nodePub key.NodePublic, discoPub key.DiscoPublic) []byte {
    // Format: [meowMagic][nodePub][discoPub]
    // Allows the server to authenticate and prepare WireGuard config
}

Lines 67–71 define EncodeMeowed, which creates the acknowledgment packet the server sends back to confirm successful peer registration. The symmetric ParseMeowPing function extracts these keys from received packets, enabling the server to construct the necessary cryptographic state to communicate with the new peer.

The Handshake Flow

The Meow handshake follows a strict two-message pattern over DERP:

  1. Client sends EncodeMeowPing containing its identity keys to the server's DERP region
  2. Server validates the client against AllowedClients, installs the peer in its WireGuard configuration via onMeow, and replies with EncodeMeowed
  3. Client receives the acknowledgment, discards further Meow processing, and initiates the WireGuard handshake

This exchange replaces the traditional control plane's role in peer introduction and key distribution.

WireGuard User-Space Engine Integration

Once the Meow handshake completes, Tailcat must configure the actual encrypted mesh. It accomplishes this through the wgengine package, using lazy initialization to avoid race conditions during peer admission.

Lazy Configuration and Engine Creation

The createEngine function in tailcat.go (lines 1562–1565) instantiates a user-space WireGuard engine with a specific configuration that derives Disco keys deterministically from node private keys:

// From tailcat.go#L1562-L1565 and tailcat.go#L18-L24
cfg := &wgengine.Config{
    ForceDiscoKey: discoPrivKey,
    // ...
}
engine, err := wgengine.NewUserspaceEngine(logf, cfg)

The ForceDiscoKey option (referencing lines 18–24) ensures that both ends of the connection generate identical Disco keys from their respective node private keys, enabling the Disco protocol to function without prior key exchange.

NetworkMap Construction in onMeow

When onMeow processes a valid Meow Ping, it constructs a NetworkMap describing the mesh topology and pushes it to MagicSock. As shown in lines 90–144 of tailcat.go, this method:

  • Generates a ULA (Unique Local Address) for the new peer using tcAddrForKey
  • Builds a NetworkMap containing both the server and the newly admitted client
  • Invokes mc.SetNetworkMap to update the local network state
  • Calls sys.Netstack.Get().UpdateNetstackIPs to configure the IP routing layer

This sequence installs the peer into the Netstack and WireGuard engine without requiring a control plane to push network topology updates.

Direct-Path Discovery with Disco

After the initial DERP-mediated handshake, Tailcat transitions to direct UDP connections using the Disco protocol. Both nodes already possess each other's Disco public keys (derived from the node keys exchanged in the Meow Ping), allowing them to skip the traditional DERP-based discovery phase.

NAT Traversal via Call-Me-Maybe

Using the shared Disco keys established during the Meow handshake, nodes exchange "call-me-maybe" frames that advertise their UDP endpoints. This standard Tailscale NAT traversal technique enables the establishment of direct UDP paths that bypass DERP for subsequent data transmission. The WireGuard engine, now aware of the peer through the NetworkMap update, encrypts all traffic over this direct path.

Practical Implementation Example

Deploying a Tailcat server requires only a few lines of Go code, with no external coordination services:

// Server initialization from tailcat.go patterns
s := &tailcat.Server{
    AllowedClients: map[key.NodePublic]bool{
        clientKey: true, // Optional whitelist
    },
}
if err := s.Start(context.Background()); err != nil {
    log.Fatalf("server start: %v", err)
}

The Start method internally creates the DERP-connected locoBackend, registers the onDERPRecv callback, and initializes the user-space WireGuard engine. Clients connect by dialing the server's public key through any DERP region:

c := &tailcat.Client{
    ServerDERPRegion: tailcfg.DERPRegionID(1),
}
if err := c.Dial(ctx, serverPublicKey); err != nil {
    log.Fatalf("dial failed: %v", err)
}

The client automatically sends the Meow Ping, waits for the Meowed acknowledgment, and transitions to direct WireGuard communication.

Summary

  • DERP as bootstrap: Tailcat repurposes existing DERP relays to handle the initial handshake, eliminating the need for a dedicated coordination server.
  • Meow protocol: Custom DERP packets defined in disco.go (EncodeMeowPing, EncodeMeowed) carry identity information and establish peer relationships directly between nodes.
  • Lazy WireGuard configuration: The onMeow method in tailcat.go dynamically builds a NetworkMap and updates the user-space engine via mc.SetNetworkMap without control plane involvement.
  • Direct path establishment: Disco keys derived from node private keys enable immediate NAT traversal after the Meow handshake completes.
  • Zero external dependencies: The entire system operates using subsystems already present in Tailscale nodes, requiring only the DERP relay infrastructure that serves as a fallback transport.

Frequently Asked Questions

How does Tailcat authenticate peers without a central control plane?

Tailcat relies on cryptographic authentication via the Meow Ping protocol. When a client sends a EncodeMeowPing packet containing its node public key, the server validates this against an optional AllowedClients map or accepts any validly signed introduction. The WireGuard layer subsequently enforces cryptographic identity, ensuring that only holders of the corresponding private keys can participate in the mesh.

What prevents unauthorized nodes from joining a Tailcat network?

The server implementation in tailcat.go includes an AllowedClients field that functions as an access control list. During the onDERPRecv callback processing, the server checks whether the client's node public key exists in this map before calling onMeow to add the peer. If the check fails, the Meow packet is ignored, and no WireGuard configuration is created for that node.

Can Tailcat establish direct connections through NATs and firewalls?

Yes. After the initial DERP-mediated Meow handshake, both nodes possess each other's Disco public keys. They use the standard Tailscale Disco protocol to exchange "call-me-maybe" messages that advertise UDP endpoints, facilitating NAT traversal. Once a direct path is discovered, traffic flows over encrypted WireGuard UDP packets, bypassing the DERP relay entirely.

Does Tailcat require any infrastructure beyond standard Tailscale components?

No. Tailcat utilizes only subsystems present in every Tailscale node: the DERP client for initial packet relay, the Disco protocol for endpoint discovery, and the user-space WireGuard engine for encryption. The DERP servers act purely as message routers for the Meow handshake and as fallback relays, requiring no Tailcat-specific modifications to operate.

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 →