LogoPear Docs

Relay connections through a blind relay

Run a blind relay and point peers at it with --relay, for networks where hole punching cannot establish a direct connection.

Most peers reach each other directly: hole punching opens a path through both firewalls and the connection carries on without a middleman. On some networks it cannot. A randomizing NAT—common on corporate and carrier-grade networks—assigns an unpredictable external port per connection, so neither side can tell the other where to dial.

A blind relay is the fallback: a third machine that forwards encrypted stream messages between two peers that cannot meet directly. It is "blind" in the same sense as a blind peer—it moves bytes it cannot read. Unlike a blind peer, it stores nothing; it only forwards live connections.

Since Pear 3.4.0 this is built into the CLI: pear blind-relay start runs the relay, and --relay <key> points a peer at one.

Before you start

You need a third machine that both peers can reach—a VPS or any always-on host with working connectivity. A relay on one of the two peers' own networks defeats the purpose: if that network is the one blocking direct connections, it cannot rescue them.

Run the relay

On the relay host:

pear blind-relay start

It prints a live table. The first row is the one you need:

 Public Key:          <relay-key>
 Sessions Accepted:   0
 Sessions Opened:     0
 Sessions Closed:     0
 Sessions Active:     0
 Pairings Requested:  0
 Pairings Matched:    0
 Pairings Pending:    0
 Pairings Active:     0
 Streams Opened:      0
 Streams Closed:      0
 Streams Errors:      0
 Streams Active:      0

Copy <relay-key>. That is what peers pass to --relay.

The relay's key pair is derived from the platform corestore on that machine, so the key is stable across restarts—note it down once and reuse it. The process must stay running to relay anything; put it under a service manager for anything long-lived.

Only one relay runs per sidecar. Starting a second fails with Blind relay is already running, cannot start another.

Point a peer at the relay

On each peer that needs relaying, pass the relay's key once:

pear --relay <relay-key> info

Any command works—info is just a cheap one to run. The point is the flag, not the command.

--relay registers the relay with the sidecar, the shared background process, not with the command you attached it to. That has two consequences worth knowing up front:

  • You only need to pass it once. It stays in effect for everything that sidecar does afterwards, so there is no need to add --relay to every subsequent command.
  • There is no flag that unsets it. To stop relaying, restart the sidecar with pear sidecar shutdown.

An invalid key is rejected before the command runs:

--relay <key> must supply a valid public key

What actually happens next

Registering a relay does not push your traffic through it. The swarm keeps connecting directly whenever it can, and consults the relay only when a connection genuinely needs relaying—or when this machine's DHT node is randomized, which is the unpredictable-NAT case hole punching cannot solve.

So on a healthy network you may register a relay and never see it carry a byte. That is the intended behaviour, not a misconfiguration.

Confirm it is working

Watch the relay's table while the peers connect. Relayed traffic moves these counters:

  • Pairings Requested / Matched — two peers asked the relay to introduce them, and it matched them by token. A request that never matches means only one side reached the relay.
  • Streams Opened / Active — forwarding is underway.
  • Streams Errors — forwarded streams that failed.

Sessions count peers connected to the relay itself, so a peer that registered the relay but never needed it shows a session with no pairings.

If the counters stay at zero while two peers fail to connect, check in this order:

  1. Both peers registered the same relay key—--relay on one side only cannot pair.
  2. The relay host is reachable from both peers, and pear blind-relay start is still running.
  3. The peers' sidecars actually picked the flag up. Each sidecar keeps its own relay setting, and it is lost on restart—if a sidecar restarted, pass --relay again.

See also

On this page