When frp Goes Peer to Peer: XTCP, NAT Hole Punching, and Fallback
XTCP is frp’s attempt to change the data path after two clients have been introduced through frps. The useful question is not whether XTCP “bypasses the server,” but which work remains on the server, what network evidence the endpoints exchange, and under what conditions their payload can travel directly. Following that sequence makes the feature’s value clear without turning an opportunistic NAT-hole attempt into a universal connectivity promise.
Direct payload still begins with server coordination
In an ordinary relayed proxy, frps remains between the public or visitor connection and the local service for the lifetime of the payload. XTCP tries to move the payload between two frp clients: a visitor client that wants to reach the service and the client that owns the XTCP proxy. The public server is still needed to introduce those participants, authenticate the request, exchange coordination messages, and tell each side how to attempt the path.
That division is the first boundary to keep in mind. A direct data path is a change in where bytes travel, not a removal of the control plane. The two endpoints do not independently guess one another’s addresses and begin sending application traffic. They ask frps to coordinate a named proxy and receive a session identifier and probing instructions. If the attempt succeeds, the server may no longer carry the payload, but it has still played the role of rendezvous point and policy gate.
The process starts with a pre-check. The visitor asks the server whether the target XTCP proxy exists and whether the visitor user is permitted. The server’s NAT-hole controller can reject a missing proxy or a visitor outside the configured allow-list before the more expensive discovery and probing work begins. The service owner’s XTCP proxy also has a secret key, and the visitor later signs its request with a time-based value derived from that secret. Directness does not mean unauthenticated reachability.
STUN turns hidden mappings into candidates
A private client usually knows its local UDP socket, but the peer needs to know how the network edge maps that socket onto a public address and port. XTCP uses STUN to discover mapped addresses. Each endpoint contacts the configured STUN service and records the address observed from outside. It can also collect assisted addresses from local network interfaces when that option is enabled. These two kinds of address are evidence for the attempt, not a guarantee that a packet sent to them will arrive at the intended socket.
The distinction follows from NAT itself. A network edge can map different destinations to different external ports, change mappings over time, or apply behavior that makes an address learned from one observation unsuitable for a packet from the peer. A local interface address may be reachable in one shared network but meaningless across the public Internet. XTCP therefore sends mapped and, where allowed, assisted addresses to frps, which can provide them to the other endpoint as candidates.
The preparation step also classifies NAT behavior.