Edge · Splice · Link · Hub · Beam · eBPF

No IPs.
No Ports.
No Exposure.

This is the optional Gateway architecture. Activate it and every DYLARIS game server becomes invisible to the public internet — player traffic enters through disposable Edge nodes, files flow through Beam, the node itself never exposes a port. Without the Gateway, DYLARIS runs like any other host: public IPs, SFTP, port 25565.

DockerAll services ship as Docker containers. Single-command deploy anywhere.
Edge
5,313
lines Go
Link
1,444
lines Go
Hub
1,752
lines Go
Beam
1,166
lines Go
eBPF
216
lines C
01 · Overview

Traffic Flow

CLIENTPlayer:25565TCPVPS / EDGE NODESPLICE🐳 sidecar containerTCP AcceptTCP Forward → EdgeSession Spliceconn lifecycleno L7 logicEDGE🐳 docker containereBPF / XDP filterL7 Protocol ParseRoute LookupYamux → LinkmTLSYamuxsession splice bypass · no disconnect · <50msLINKTunnel Agentoutbound only🐳 dockerLANSERVERSurvival SMPSERVERCreative HubHUBControl PlaneRoute Registry🐳 dockerroute sync · 24h TTLplayer trafficsplice bypasscontrol planeLAN (private)
Data Plane

Splice and Edge are two Docker containers on the same VPS. Splice is a sidecar that handles raw TCP: accepting connections, forwarding to Edge, managing session splice. Edge owns all application logic: eBPF/XDP filtering, L7 protocol parsing, route lookup, and Yamux toward Link.

Tunnel Layer

Link agents run inside the hosting network and connect outbound to every known Edge simultaneously. No inbound ports, no firewall rules. Game server networks stay air-gapped from the internet.

Control Plane

Hub manages the routing table. It auto-discovers Edges and Links via Redis heartbeats, validates proof-of-knowledge tokens, and syncs routes to all Edges on a 24h TTL cycle.

02 · Edge

Disposable Infrastructure Layer

Docker

An Edge node is any cheap VPS or bare-metal instance running two containers: Splice (raw TCP accept, forwarding, session splice) and Edge (eBPF/XDP, L7 parsing, Yamux, routing). Only the Edge node needs a public IP. Edge nodes are intentionally disposable. Swap the IP, redeploy, update DNS. No backend servers go down. No state is lost.

Deploy time
< 60s
2x docker pull + run on any VPS
State
Stateless
all state lives in Hub/Redis
Redundancy
N+1
Link meshes to all active edges
Failover
5s
Link discovers + reconnects
Session Splicing: Rolling Edge Updates

When Edge needs updating, Splice routes past the old Edge, connecting directly to Link and transparently redirects all active TCP streams to the new Edge container. The splice happens at the raw TCP level so players experience no disconnect, only a brief lag spike of under 50ms.

edge v1.2.0 · active · 3 player sessions
edge v1.3.0 · starting · routes received from Hub
→ Splice: TCP streams bypassed to new Edge
→ streams re-attached to Edge v1.3.0 · <50ms
→ edge v1.2.0 container stopped
edge updated · no disconnects · 3 sessions live
edge-eu-01 · docker deploy
# Any VPS, 1 vCPU, 1 GB RAM is enough
$ docker run -d \
--name edge \
--network host \
--cap-add NET_ADMIN \
--cap-add SYS_ADMIN \
-e REDIS_URL=redis://hub:6379 \
-e EDGE_NAME=edge-eu-01 \
dylaris/edge:latest
image pulled · dylaris/edge:1.3.0
container started · pid 1
eBPF compiled · XDP attached eth0
registered in Redis as edge-eu-01
── Link discovers new edge ──────────
link-node-eu-01 dialing edge-eu-01…
Yamux session established
session splice: new streams → edge-eu-01
── Old edge draining ────────────────
edge-eu-00: 0 active streams · shutting down
edge-eu-00: removed from registry
✓ splice complete · <50ms · 0 disconnects
[edge] old container stopped · new edge active
03 · Edge

Public Ingress Router

5,313 LoC · GoDocker

Main service on the Edge node VPS, running alongside the Splice sidecar container. Compiles and attaches its own eBPF/XDP program at startup.

Edge is the main Docker container on the VPS, paired with the Splice sidecar. It owns all application logic: eBPF/XDP packet filtering, L7 protocol parsing to identify the target server, route lookup, and Yamux multiplexing toward Link. The Splice container handles only raw TCP accept and forwarding. Edge does the rest.

Protocols
4
HTTP · TLS/SNI · Minecraft · MC Legacy
Mux Layer
Yamux
over mTLS · multiplexed streams
XDP Hook
host NIC
NIC driver level · pre-kernel
Heartbeat
Redis
health · node discovery · session state
Protocol Detection Tree
peek(3 bytes)
├─ 0x16 0x03 * → TLS ClientHello → parse SNI
├─ GET / HTTP → HTTP/1.x → parse Host header
├─ 0xFE 0x01 0xFA → MC Legacy → parse ServerListPing
└─ VarInt len → MC Handshake → parse ServerAddress
domain extracted → lookup route → session.OpenStream()
edge · startup log · 🐳 main container on edge VPS
$ dylaris-edge --config /etc/edge/config.yaml
[edge] v1.3.0 · pid 1 · 🐳 docker
──────────────────────────────────────
Redis connected · hub:6379
TLS keypair loaded · edge-eu-01.crt
Yamux listener :8443 ready (mTLS)
registered heartbeat · edge-eu-01
── eBPF / XDP ──────────────────────
clang bpf_program.c → bpf_program.o
XDP attached · eth0 · driver mode
LRU map · 65536 entries · per-CPU
rate limit: 2000 pps / IP / 1s window
── Listeners ────────────────────────
:25565 · Minecraft (VarInt + legacy)
:443 · TLS/SNI passthrough
:80 · HTTP Host routing
✓ edge ready · waiting for links...
[link] node-eu-01 connected · session splice ready
[route] survival.play.example.com → node-eu-01
[route] creative.play.example.com → node-eu-01
04 · eBPF / XDP

Kernel-Level Firewall

216 LoC · C
bpf_program.c · XDP entry point
// Per-IP packet rate limiter, runs in kernel
// Compiled via bpf2go at container startup
struct
bpf_map_def SEC("maps") ip_counter_map = {
.type = BPF_MAP_TYPE_LRU_PERCPU_HASH,
.key_size = sizeof(__u32), // IPv4 addr
.value_size = sizeof(__u64), // packet count
.max_entries = 65536,
};
SEC
("xdp") int xdp_filter(struct xdp_md *ctx) {
// Extract source IPv4
struct
iphdr *ip = data + sizeof(ethhdr);
// Check CIDR whitelist first (always pass)
if
(cidr_lookup(ip->saddr)) return XDP_PASS;
// Increment per-IP counter (per-CPU, lock-free)
__u64
*cnt = bpf_map_lookup_elem(
&ip_counter_map, &ip->saddr);
if
(cnt && ++(*cnt) > RATE_LIMIT_PPS)return XDP_DROP; // ← drop in kernel
return
XDP_PASS;
}

The XDP program is a 216-line C file compiled to a BPF object at Edge container startup via bpf2go + clang. It attaches to the NIC in driver mode. Packets are inspected before they touch the kernel networking stack. No Docker networking overhead.

Drop latency
~50ns
kernel driver hook vs ~5µs userspace
Map type
LRU_PERCPU
no locking, each CPU core independent
Capacity
65,536
concurrent IPs tracked simultaneously
Rate limit
2,000 pps
per IP per second, 1s rolling window
Whitelist
CIDR
trusted CIDRs bypass rate limiter entirely
Compile pipeline
bpf2go bpf_program.c
→ clang -O2 -target bpf
→ bpf_program_bpfeb.o
→ bpf.Link.AttachXDP(eth0)
runs at container start · no pre-compile needed
05 · Link

Zero-Port Tunnel Agent

1,444 LoC · GoDocker

Runs as a Docker container (or systemd service) inside the hosting network. Zero inbound ports required.

Link is a small Go binary that ships as a single Docker container and runs inside your hosting network. It never opens any inbound ports. Instead, it dials out to all known Edges simultaneously, establishing persistent mTLS/Yamux sessions. Player traffic flows back through these sessions in reverse. When an Edge is replaced, Link automatically session-splices to the new one.

Edge Discovery Providers
RedisSubscribes to Edge list from shared Redis. New Edge nodes auto-discovered as soon as Edge registers.
StaticHardcoded Edge address list. Used in air-gapped setups where Redis isn't shared.
PushEdge sends a connect request to Link via Redis pubsub. Link dials back within 200ms.
Reconnect
5s
mesh reconciliation interval
IP priority
private
10.x / 192.168.x tried first
Auth
SHA-256
token = H(edgeName:secret)
TLS
fingerprint
cert hash validated per-Edge
link · node-eu-01 · 🐳 docker
$ docker run dylaris/link:latest --node node-eu-01
[link] v0.8.0 · zero inbound ports
Redis provider · hub:6379
2 edge gates discovered
── Connecting to all edges ──────────
edge-eu-01 · 10.0.1.50:8443 (private)
edge-eu-01 · Yamux session ready
edge-eu-02 · 10.0.1.51:8443 (private)
edge-eu-02 · Yamux session ready
✓ mesh ready · 2/2 edges connected
── Rolling update detected ──────────
edge-eu-03 · new edge discovered
edge-eu-03 · session splice activated
edge-eu-01 · draining · removed
>
06 · Hub

Control Plane

1,752 LoC · GoDocker

Hub is the cluster state manager. It ships as a Docker container alongside PostgreSQL and Redis. It knows every Edge, every Link, every route. It uses Redis heartbeats to auto-discover infrastructure without manual registration. Routes are stored in PostgreSQL (via GORM) with per-tenant table namespacing and pushed to all Edges on a 24-hour TTL sync cycle, including newly deployed Edge nodes.

Redis Auto-Discovery

Edges and Links publish heartbeats to Redis. Hub reads these, validates proof-of-knowledge tokens, and registers them (including freshly deployed Edge containers) without any manual API call.

Proof-Based Auth

No raw secrets in Redis. Each node publishes H(secret || nonce). Hub verifies locally. A replay attack from Redis gives an attacker nothing usable.

Multi-Tenant Namespacing

All Hub tables use a configurable prefix (dylaris_hub_*). Multiple Hub instances share one PostgreSQL cluster without schema conflicts.

Route Sync · 24h TTL

Hub re-validates all routes every 24h. Stale routes are purged from all Edge routing tables, including after rolling updates replace old containers.

Hub Data Model
edges · id, host, port, fingerprint, last_seen
links · id, node_id, edges[], status
routes · domain, target_link, port, ttl
clusters · id, name, prefix, owner
Route Lifecycle
Core calls Hub REST API
Hub writes route to DB
Hub pushes to all active Edges
New Edge gets routes on connect
24h TTL · Hub re-validates
stale routes purged from all edges
07 · Beam

File Infrastructure Relay

1,166 LoC · Go + WailsDocker

Beam eliminates FTP/SFTP entirely. The Beam Relay runs as a Docker container in the hosting network. It handles token authentication and connection routing. The desktop client (Wails/Go) connects to the relay and streams files directly to Node containers via Yamux-multiplexed gRPC over TLS. No legacy file transfer protocols, no exposed ports.

Beam Relay

~900 LoCCOMPLETE

Accepts Beam client connections, validates short-lived tokens from Redis (beam:token:{uuid}), and proxies streams to the correct Node Docker container. Yamux multiplexing. One TLS connection supports concurrent file operations.

Desktop Client (Wails)

~266 LoCIN PROGRESS

Native desktop app (Go + WebView2) that ships as a standalone installer. File browser UI complete and REST-based. Tunnel-based streaming architecture implemented in Relay and ready. Client-side integration in progress.

beam relay · 🐳 docker · token flow
// 1. Core issues short-lived token
SET beam:token:{uuid} "nodeId:userId:rw"
EX 300 // 5 minute TTL
// 2. Desktop client dials relay
TLS dial beam.relay:9090
send token → relay validates via Redis
// 3. Relay proxies to Node container
token valid · node-eu-01 · user 42 · rw
Yamux session → node-eu-01 container
stream 0 → ls /data/survival/
stream 1 → upload world/level.dat (14 MB)
transfer: 14.2 MB · 3.8 MB/s · done
Protocol
Yamux
over mTLS · multiplexed
Token TTL
5 min
Redis · auto-expire
No SFTP
zero legacy protocol surface
08 · Positioning

vs. Conventional Hosting Infrastructure

Every other approach exposes server IPs to the public internet. DYLARIS doesn't.

ApproachZero Exposed IPsKernel DDoSMC ProtocolRolling UpdatesFull PanelDocker-Native
DYLARIS
Traditional Panel Hosting
Each server needs its own IP. One DDoS → server offline.
~~
BungeeCord / Velocity
MC proxy only. Still exposes the proxy IP. No DDoS layer.
Cloudflare Tunnel
TCP tunneling only. No Minecraft protocol parsing, no eBPF, no panel.
~
Pterodactyl / Pelican
Panel + Docker orchestration, but servers still fully exposed.
Ngrok / frp
General TCP tunneling. No DDoS, no protocol awareness, no panel.

The Only Portless Stack

DYLARIS is the only game hosting platform where backend servers have zero public-internet presence. No IP to expose. No port to DDoS. Link connects outbound only.

Protocol-Aware at the Edge

Edge understands Minecraft VarInt handshakes, TLS SNI, and HTTP Host headers natively. Run 1,000 servers on a single IP and port. No SRV records, no proxy fleet.

Kernel Drops, Not Null Routes

eBPF/XDP filters run before the kernel networking stack. ~50ns drop latency. Not scrubbing centers, not rate-limiting in nginx. Packets die at the NIC driver.

09 · Summary

Component Overview

ComponentRoleProtocolOpen PortsDockerLoC
Edge Node
Disposable VPS · hosts Edge + Splice containersn/a25565, 443, 80VPSn/a
Edge
Public ingress, L7 routing, eBPF/XDPMinecraft · TLS/SNI · HTTP · Yamux25565, 443, 80image5,313
Splice
TCP accept sidecar, rolling-update bypassraw TCP(via Edge node)sidecar~600
Link
Outbound tunnel agent, session splicemTLS + Yamux (outbound only)noneimage1,444
Hub
Control plane, route registrygRPC + RESTinternalimage1,752
Beam Relay
File transfer relay, token authYamux over TLS9090 (internal)image~900
eBPF/XDP
Kernel-level packet filterXDP_DROP / XDP_PASSNIC hookcompiled in Edge216 C
Dylaris

Built to host at scale.

Edge · Splice · Link · Hub · Beam. A complete, Docker-native hosting infrastructure stack. Currently in active development.