Get AI summaries of any video or article — Sign up free
did i just finish my reverse proxy????? thumbnail

did i just finish my reverse proxy?????

The PrimeTime·
6 min read

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.

TL;DR

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?

It uses “packet framers” that implement a hand-rolled packet format. The framing logic reads specific bytes to determine the packet length (described as using the third and fourth bytes as the length). With the length known, the proxy avoids heavy parsing and forwards the packet payload efficiently. This framing is applied on both the client-facing side and the game-server-facing side so the proxy can reliably relay discrete packets over a stream-oriented TCP connection.

What is the end-to-end connection flow from client connect to game-server routing?

First, the proxy checks whether a new connection is allowed. Then it creates context wrappers and waits for the first packet, which must be an “off/auth packet.” If authentication fails or the packet is missing/invalid, the proxy removes the connection. If authentication succeeds, the proxy performs server selection: if no server is available, it triggers server creation. Next, it opens a new TCP connection to the selected game server, creates a reader for that socket, and waits for the game-server authentication response so the proxy can confirm the server is ready to accept the client. Only then does it forward the authenticated state back to the client and start bidirectional forwarding.

What does the project use to test the system before running the proxy in a real environment?

It builds a simulation network backed by SQLite. A “no server” file is essentially a SQLite database generated from hand-built configuration tables. The environment can be hydrated into specific states, including preloaded tables and active connections. A factory creates clients, connects them, asserts that they reach both the matchmaking layer and the game server, checks server-farm stats, then disconnects and verifies stats again. Runs are time-bounded (e.g., failing if a test lasts longer than five seconds) to catch hangs or runaway behavior.

How are server instances created and synchronized with the proxy’s routing decisions?

When server selection can’t find an available server, the proxy triggers a “create and wait” mechanism. Locally, this spawns a new process that starts a TCP server and signals readiness by writing data into SQLite. The waiting process monitors SQLite until the server’s readiness data appears, then returns a ready server endpoint so the proxy can connect and proceed with the authentication handshake.

What security and abuse-mitigation concerns shape the proxy design?

The builder is concerned that direct client-to-game-server connections could let attackers target game servers to disrupt other players. A reverse proxy can centralize defenses, but it also becomes a shared choke point. Planned mitigations include rate limiting, validating packet behavior, having game servers close/kick abusive clients, and potentially banning IPs after repeated issues. There’s also interest in moving packet filtering down to eBPF for maximum performance once the basic proxy works reliably.

Why does the project emphasize reproducible simulation randomness?

The builder wants stress tests where connection drops, client placement, and random events occur in a deterministic order every run. That reproducibility would make it easier to compare results across iterations and debug failures, because the same sequence of randomized events can be replayed exactly.

Review Questions

  1. What specific bytes does the proxy use to determine packet length, and how does that choice affect forwarding efficiency?
  2. Describe the authentication handshakes that must succeed before the proxy begins relaying packets between client and game server.
  3. How does the SQLite-backed simulation environment support repeatable testing of server selection, connection lifecycles, and server-farm stats?

Key Points

  1. 1

    Clients connect to a TCP reverse proxy, send an initial authentication packet, and only then get routed to a game server.

  2. 2

    Server selection checks for available servers and can spawn new game server processes when none are ready.

  3. 3

    The proxy forwards traffic using custom packet framing that reads packet length from fixed byte positions to preserve message boundaries over TCP.

  4. 4

    Bidirectional lifecycle handling forwards connection-close events and tears down both sides on errors to avoid dangling sockets.

  5. 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. 6

    Security plans include centralized rate limiting and packet behavior checks, with longer-term ideas like eBPF-level filtering and IP banning.

  7. 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.

Highlights

The proxy’s core job is routing: authenticate a TCP client, select (or create) a game server, open a second TCP connection, then relay packets both ways until disconnect.
Packet framing is intentionally minimal—packet length is read from specific bytes, and payloads are forwarded without deep parsing for efficiency.
Testing relies on a deterministic simulation environment built from SQLite configs, with a client factory and assertions that validate both connectivity and server-farm stats.
Security trade-offs are explicit: a reverse proxy can reduce direct exposure of game servers, but it also concentrates risk at the proxy, motivating rate limits and low-level filtering ideas.

Topics

  • TCP Reverse Proxy
  • Game Server Selection
  • Custom Packet Framing
  • SQLite Simulation Testing
  • eBPF Packet Filtering

Mentioned

  • TCP
  • SQL
  • eBPF