did i just finish my reverse proxy?????
Based on The PrimeTime's video on YouTube. If you like this content, support the original creators by watching, liking and subscribing to their content.
Clients connect to a TCP reverse proxy, send an initial authentication packet, and only then get routed to a game server.
Briefing
A homegrown reverse proxy is being built to sit between TCP game clients and dynamically selected game servers—handling authentication, server selection, and bidirectional packet forwarding while keeping connection lifecycle clean. The core goal is straightforward: a client connects, sends an authentication packet, the proxy verifies it, chooses (or creates) an appropriate game server, opens a new TCP connection to that server, and then relays packets back and forth until either side disconnects.
The system’s flow starts with a custom TCP protocol rather than HTTP. After the client connects, the proxy expects an initial “auth packet” identifying the client. Once authentication succeeds, the proxy checks available servers. If none are suitable, it triggers a server-creation path—described as “matchmaking” but more accurately server selection—so the client can be routed to a ready game instance. When a server is selected, the proxy establishes a second TCP connection to the game server, forwards any initial game settings back to the client, and then enters a middle-man loop that forwards packets in both directions.
A key implementation detail is how packets are framed over raw TCP. Because TCP is reliable but not message-oriented, the proxy uses “packet framers” to parse a hand-rolled packet format. The framing logic is intentionally lightweight: it reads specific bytes to determine packet length, then forwards the packet payload without deeper parsing. Connection handling is similarly direct: it watches for connection-close events and errors, writes close signals across the wire, and tears down both sides when either endpoint disconnects.
Before the proxy logic, the project invests heavily in simulation testing. A local environment is created using a SQLite-backed configuration and tables. Test runs can be bounded (for example, failing if they exceed five seconds), and the environment can be hydrated into known states with preconfigured tables and connections. A factory generates clients, connects them, asserts that clients reach both the matchmaking layer and the game server, and verifies server-farm stats before disconnecting and re-checking. The result is a repeatable harness that can run through connection and lifecycle scenarios without needing live infrastructure.
On the proxy side, the code checks whether new connections are allowed, wraps connection context, authenticates the first packet, performs server selection, then creates and verifies a game-server-side authentication handshake before granting the client access. Lifecycle management is handled by running the same packet-forwarding logic for both directions, with deliberate duplication to avoid premature abstraction.
Security and scaling trade-offs are front and center. The builder worries that letting clients connect directly to game servers could enable attacks aimed at disrupting other players. A reverse proxy can centralize defenses, but it also becomes a shared target—so the plan includes rate limiting, packet behavior checks, and potentially server-side logic to kick or ban abusive clients. There’s also a strong pull toward pushing filtering down to eBPF for performance, after gaining confidence that the current “fun first” implementation won’t break core assumptions.
The biggest takeaway is less about any single proxy feature and more about the value of good simulations: the builder wants randomized client placement, drops, and connection ordering to be reproducible in the exact same sequence every run, enabling more reliable stress testing as the system approaches production readiness.
Cornell Notes
The project builds a TCP reverse proxy for a game backend. Clients connect to the proxy, send an authentication packet, and the proxy verifies identity before selecting an available game server (or spawning one if none exist). After opening a second TCP connection to the chosen game server, the proxy forwards packets both ways using a custom framing scheme that reads packet length from specific bytes and then relays payloads with minimal parsing. A SQLite-backed simulation environment and client factory are used to test connection lifecycles, server-farm stats, and time-bounded runs. The approach matters because it centralizes authentication and routing while creating a foundation for later security controls like rate limiting and low-level packet filtering (potentially via eBPF).
How does the proxy handle TCP’s lack of message boundaries when forwarding game traffic?
What is the end-to-end connection flow from client connect to game-server routing?
What does the project use to test the system before running the proxy in a real environment?
How are server instances created and synchronized with the proxy’s routing decisions?
What security and abuse-mitigation concerns shape the proxy design?
Why does the project emphasize reproducible simulation randomness?
Review Questions
- What specific bytes does the proxy use to determine packet length, and how does that choice affect forwarding efficiency?
- Describe the authentication handshakes that must succeed before the proxy begins relaying packets between client and game server.
- How does the SQLite-backed simulation environment support repeatable testing of server selection, connection lifecycles, and server-farm stats?
Key Points
- 1
Clients connect to a TCP reverse proxy, send an initial authentication packet, and only then get routed to a game server.
- 2
Server selection checks for available servers and can spawn new game server processes when none are ready.
- 3
The proxy forwards traffic using custom packet framing that reads packet length from fixed byte positions to preserve message boundaries over TCP.
- 4
Bidirectional lifecycle handling forwards connection-close events and tears down both sides on errors to avoid dangling sockets.
- 5
A SQLite-backed simulation harness hydrates known states, generates clients, asserts routing to game servers, and verifies server-farm stats with time-bounded runs.
- 6
Security plans include centralized rate limiting and packet behavior checks, with longer-term ideas like eBPF-level filtering and IP banning.
- 7
Server creation uses a “spawn then wait for SQLite readiness” pattern so the proxy can connect only after a server signals it is ready.