MCPcopy Index your code
hub / github.com/HyBuildNet/quic-relay

github.com/HyBuildNet/quic-relay @v0.14

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.14 ↗ · + Follow
256 symbols 840 edges 25 files 178 documented · 70%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

QUIC Relay

QUIC Relay

CI

A reverse proxy for Hytale servers/Raw QUIC SNI parsing. Route players to different Hytale-Servers based on the domain they connect to. According to Hytale's official server guide the "Minecraft"-like SRV implementation is not yet available (source). And therefore a QUIC-Proxy might be the only convenient way for achieving standard port + multiple servers.

flowchart LR
    A[Player A] -->|play.example.com| P[QUIC Relay :5520] --> S1[play.example.com]
    B[Player B] -->|lobby.example.com| P --> S2[127.0.0.1:5521]
    C[Player C] -->|minigames.example.com| P --> S3[minigames.dev:67344]

Quickstart

curl -sSL https://raw.githubusercontent.com/HyBuildNet/quic-relay/master/dist/install.sh | sudo bash
sudo systemctl enable --now quic-relay

Configure via /etc/quic-relay/config.json. Reload with systemctl reload quic-relay.

Docker

docker run -p 5520:5520/udp ghcr.io/hybuildnet/quic-relay:latest
podman run -p 5520:5520/udp ghcr.io/hybuildnet/quic-relay:latest

Or mount your config:

docker run -p 5520:5520/udp -v /path/to/config.json:/data/config.json ghcr.io/hybuildnet/quic-relay:latest

Handlers

Handlers form a chain. Each handler processes the connection and either passes it to the next handler (Continue), handles it (Handled), or drops it (Drop). Custom handlers can be implemented quite easily, but the project needs to be recompiled.

sni-router

Routes connections to different backends based on SNI. Each route can be a single backend or multiple backends (array) for round-robin load balancing. Connections with unknown SNI are dropped.

{
  "listen": ":5520",
  "handlers": [
    {
      "type": "sni-router",
      "config": {
        "routes": {
          "play.example.com": "10.0.0.1:5520",
          "lobby.example.com": ["10.0.0.2:5520", "[2001:db8::1]:5520"],
          "minigames.example.com": "myserver.internal.dev:5520"
        }
      }
    },
    {"type": "forwarder"}
  ]
}

[?] Why do we need the {"type": "forwarder"} here? The forwarding logic is implemented as a handler itself, this way we can easily replace the forwarding logic with some kind of terminating-logic, which can read the Hytale-Protocol itself and is capable to dig deeper into the game logic rather than just proxy traffic through.

simple-router

Routes all connections to one or more backends. Use backend for a single destination or backends for round-robin load balancing.

{
  "listen": ":5520",
  "handlers": [
    {"type": "ratelimit-global", "config": {"max_parallel_connections": 10000}},
    {
      "type": "simple-router",
      "config": {
        "backends": ["10.0.0.1:5520", "10.0.0.2:5520", "[2001:db8::1]:5520"]
      }
    },
    {"type": "forwarder"}
  ]
}

ratelimit-global

Limits the total number of concurrent connections. New connections are dropped when the limit is reached.

forwarder

Forwards packets to the backend. Must be the last handler in the chain.

logsni

Logs the SNI of each connection. Useful for debugging.

{
  "listen": ":5520",
  "handlers": [
    {"type": "logsni"},
    {"type": "sni-router", "config": {"routes": {"play.example.com": "10.0.0.1:5520"}}},
    {"type": "forwarder"}
  ]
}

Advanced

Global config options

{
  "listen": ":5520",
  "session_timeout": 600,
  "handlers": [...]
}
  • session_timeout - Idle session timeout in seconds (default: 600 = 10 minutes). Sessions without traffic are cleaned up after this duration. Can be changed via hot-reload (SIGHUP).

Environment variables

Fallback when not set in config: - QUIC_RELAY_LISTEN - Listen address (default: :5520) - QUIC_RELAY_BACKEND - Backend address for simple-router

Build

make build

Produces bin/proxy.

License

MIT License. See LICENSE for details.

[!] This project is neither related to nor affiliated with HYPIXEL STUDIOS CANADA INC. or any other Trademark owner of Hytale.

Extension points exported contracts — how you extend this code

Handler (Interface)
Handler is the interface that all handlers must implement. [8 implementers]
internal/handler/handler.go
HandlerFactory (FuncType)
HandlerFactory creates a handler from JSON config.
internal/handler/registry.go

Core symbols most depended-on inside this repo

Error
called by 47
internal/proxy/parser.go
Printf
called by 37
internal/debug/debug.go
Set
called by 19
internal/handler/context.go
Close
called by 16
internal/handler/context.go
readVarInt
called by 13
internal/proxy/parser.go
String
called by 12
internal/proxy/parser.go
PutBuffer
called by 12
internal/handler/bufpool.go
NewCryptoAssembler
called by 9
internal/proxy/proxy.go

Shape

Function 115
Method 104
Struct 31
TypeAlias 4
FuncType 1
Interface 1

Languages

Go100%

Modules by API surface

internal/proxy/proxy.go41 symbols
internal/proxy/parser.go22 symbols
internal/handler/handler_test.go21 symbols
internal/handler/terminator.go20 symbols
internal/handler/context.go20 symbols
internal/handler/handler.go14 symbols
internal/proxy/pool.go10 symbols
internal/proxy/proxy_test.go9 symbols
internal/handler/terminator_test.go9 symbols
internal/handler/sni_router.go9 symbols
internal/handler/simple_router.go8 symbols
internal/handler/ratelimit_global.go8 symbols

For agents

$ claude mcp add quic-relay \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact