The Rethink Private Network (RPN) is a specialized proxy subsystem designed to integrate third-party VPN providers and regional exit nodes into the Firestack network stack. It primarily facilitates integration with Windscribe, manages dynamic WireGuard configuration generation, handles account session lifecycles, and provides a thread-safe wrapper for regional proxy forking and replacement.
The RPN subsystem acts as a high-level orchestrator for WireGuard-based proxies that require external authentication and dynamic server discovery. It bridges the gap between the low-level wgproxy implementation and high-level account management.
| Component | Role | Code Entity |
|---|---|---|
| RPN Provider | Manages account registration, session tokens, and server lists. | rpn.WsClient intra/ipn/rpn/yegor.go193-214 |
| RPN Wrapper | A thread-safe rpnp struct that wraps a Proxy to allow in-place replacement. | ipn.rpnp intra/ipn/rpn.go35-53 |
| Regional Config | Metadata and UAPI generators for specific regional exit nodes. | rpn.RegionalWgConf intra/ipn/rpn/regional.go20-52 |
| Account Interface | Abstract representation of an RPN account (Windscribe, etc.). | rpn.RpnAcc intra/ipn/rpn/cfg.go54-59 |
The following diagram illustrates how an RPN request moves from account registration to the creation of a functional WireGuard proxy.
Sources: intra/ipn/rpn/yegor.go91-122 intra/ipn/rpn/regional.go69-118 intra/ipn/rpn.go273-280
The Windscribe integration (internally codenamed yegor) handles the complex lifecycle of ephemeral and permanent WireGuard credentials.
Registration involves several primary API paths:
/init: Registers client identity and generates Preshared Keys. Excessive calls trigger error 1313 (ekeylimit) intra/ipn/rpn/yegor.go51-67 intra/ipn/rpn/yegor.go147/connect: Reserves a dynamic interface on the remote server. This reservation is active while connected and up to 4 minutes after disconnect intra/ipn/rpn/yegor.go92-102wswgpermanentpath allows static WireGuard configs that do not expire automatically intra/ipn/rpn/yegor.go103-106 The system can manage up to 5 permanent keys intra/ipn/rpn/yegor.go133The system fetches a regionalized server list from serverlist/mob-v2/1/ intra/ipn/rpn/yegor.go122 It filters servers based on:
wsMinServerLinkSpeed) intra/ipn/rpn/yegor.go128wsMaxServerHealth) intra/ipn/rpn/yegor.go129onlyPremiumServers intra/ipn/rpn/yegor.go157-158Sources: intra/ipn/rpn/yegor.go31-143 intra/ipn/rpn/yegor.go146-161
RPN converts regional server metadata into WireGuard UAPI (User-space API) configuration strings at runtime.
The RegionalWgConf struct contains the necessary fields to generate a full WireGuard config, including ClientPrivKey, ServerPubKey, and regional endpoints intra/ipn/rpn/regional.go20-52
The function MakeUapiConfig overlays permanent account credentials (WsWgCreds) onto regional server endpoints. This allows a single account to "hop" between different cities by swapping the endpoint and public_key fields while maintaining the same private_key and address intra/ipn/rpn/regional.go136-214
| UAPI Field | Source Entity | Description |
|---|---|---|
private_key | creds.PrivateKey | Decoded from Base64 to Hex via toHex() intra/ipn/rpn/regional.go61-67 |
address | creds.Address | The internal tunnel IP assigned by the provider intra/ipn/rpn/regional.go142-144 |
endpoint | rwg.ServerIPPort4 | The public IP and port of the regional exit node intra/ipn/rpn/regional.go175-178 |
preshared_key | creds.PresharedKey | Optional layer of symmetric encryption intra/ipn/rpn/regional.go206-208 |
Sources: intra/ipn/rpn/regional.go185-213 intra/ipn/rpn/regional.go61-67 intra/ipn/rpn/regional.go136-157
rpnp)Because RPN proxies are dynamic (changing regions or rotating keys), the codebase uses a wrapper called rpnp to ensure that active connections aren't dropped or corrupted during a proxy swap.
rpnp WrapperThe rpnp struct implements the Proxy interface and maintains a pointer to the current active proxy intra/ipn/rpn.go35-53 It uses a sync.RWMutex to protect access to the underlying proxy instance intra/ipn/rpn.go36
Emplace(new Proxy): This is the core function for hot-swapping. It acquires a write lock, replaces the internal proxy pointer, and triggers a cleanup of "child" proxies intra/ipn/rpn.go273-310Dial() / DialBind(): These methods are proxied to the underlying p Proxy. If the internal proxy is being replaced, the request waits for the read lock via requireProxy() intra/ipn/rpn.go102-107 intra/ipn/rpn.go228-243Sources: intra/ipn/rpn.go35-53 intra/ipn/rpn.go273-310 intra/ipn/rpn.go86-94
RPN supports "forking" a main proxy into regional variants. This allows the application to maintain a global session while simultaneously offering specific exit nodes for different apps or domains.
kids map of the parent rpnp intra/ipn/rpn.go48 When the parent is emplaced or stopped, all children are purged via PurgeAll() to ensure configuration consistency intra/ipn/rpn.go283-288RPN specifically uses Windscribe-defined error codes to trigger re-registration or reconfiguration:
ekeyinvalid (1311): Trigger to run a new /init API call as the local keypair is no longer valid on the server intra/ipn/rpn/yegor.go73-83 intra/ipn/rpn/yegor.go148enoaddr (1312): Returned if the interface IP was released by the server intra/ipn/rpn/yegor.go85-88 intra/ipn/rpn/yegor.go149Sources: intra/ipn/rpn.go35-53 intra/ipn/rpn/yegor.go73-88 intra/ipn/rpn/yegor.go146-150
The RPN system utilizes several core utilities for network endpoint discovery and data management.
The system includes functions to discover Cloudflare and Windscribe infrastructure endpoints:
WinEndpoints: Resolves endpoints for svchost, wsMyIp2, and wsMyIp to facilitate connectivity checks intra/ipn/rpn/cfg.go127-147Exit64Endpoints: Generates random IPv6 endpoints from preset NAT64 prefixes (Net6to4) for anti-censorship and translation purposes intra/ipn/rpn/cfg.go149-163RPN relies on cryptographic utilities for key generation and validation:
NewWgPrivateKey: Generates Curve25519 private keys for WireGuard, ensuring proper bit manipulation for the scalar intra/backend/ipn_wgkeygen.go79-87PipKeyProvider: Provides blind signature support for privacy-preserving authentication intra/backend/ipn_pipkeygen.go51-68 It implements the RSA Blind Signature Protocol to allow clients to obtain signatures on messages without revealing the message to the signer intra/core/brsa/brsa.go19-41PipKeyState: Manages the state of a blinded message, including the blinding factor (R), salt, and the original PipMsg intra/backend/ipn_pipkeygen.go231-243Sources: intra/ipn/rpn/cfg.go37-44 intra/ipn/rpn/cfg.go127-163 intra/backend/ipn_wgkeygen.go79-87 intra/backend/ipn_pipkeygen.go51-68 intra/backend/ipn_pipkeygen.go231-243
Refresh this wiki