feat: add selectable allocation-based privacy relay
This commit is contained in:
parent
e979da9e76
commit
46de16db00
14 changed files with 1067 additions and 43 deletions
58
docs/API.md
58
docs/API.md
|
|
@ -1,16 +1,17 @@
|
|||
# Discovery API v1
|
||||
|
||||
The API stores public room advertisements as short-lived leases and coordinates direct UDP hole
|
||||
punching. It does not proxy or relay gameplay traffic. straywild continues to connect to the
|
||||
returned host and UDP port through ENet.
|
||||
The API stores public room advertisements as short-lived leases and coordinates UDP hole punching.
|
||||
Player hosts explicitly advertise either direct or relay routing; dedicated servers must advertise
|
||||
direct routing. Public room and social-presence responses never contain a host address or port.
|
||||
Relay-enabled join responses contain only the relay endpoint.
|
||||
|
||||
All request and response bodies use `application/json`. Production clients must use HTTPS.
|
||||
|
||||
## `GET /health`
|
||||
|
||||
Returns service status, package version, configured build revision, and the number of active,
|
||||
unexpired room leases. Deployments should set `straywild_DISCOVERY_BUILD_REVISION` to the exact
|
||||
Git commit they are running. The package version follows the coordinated straywild release tag.
|
||||
Returns service status, package version, configured build revision, active room count, whether the
|
||||
relay is enabled, and the active relay allocation count. Deployments should set
|
||||
`straywild_DISCOVERY_BUILD_REVISION` to the exact Git commit they are running.
|
||||
|
||||
## `GET /v1/rooms`
|
||||
|
||||
|
|
@ -19,7 +20,9 @@ Lists active rooms. Optional exact-match filters:
|
|||
- `game_version`
|
||||
- `protocol_version`
|
||||
|
||||
The response contains `rooms` and the server's `ttl_seconds`.
|
||||
The response contains `rooms` and the server's `ttl_seconds`. Each room includes metadata plus
|
||||
either `connection_mode: "relay"` with `ip_privacy: "relayed"`, or an explicitly configured
|
||||
`direct` / `peer_visible` pair. It intentionally omits `address` and `port`.
|
||||
|
||||
## `POST /v1/rooms`
|
||||
|
||||
|
|
@ -32,13 +35,18 @@ trusting an address supplied by the game client.
|
|||
"port": 7777,
|
||||
"current_players": 0,
|
||||
"max_players": 8,
|
||||
"game_version": "0.20.2-alpha",
|
||||
"protocol_version": 12
|
||||
"game_version": "0.20.3-alpha",
|
||||
"protocol_version": 12,
|
||||
"host_kind": "player",
|
||||
"connection_mode": "relay"
|
||||
}
|
||||
```
|
||||
|
||||
`current_players` may be zero for an empty dedicated server. A player-hosted
|
||||
room normally includes its host in this count.
|
||||
room normally includes its host in this count. `host_kind` accepts `player` or
|
||||
`dedicated`. Player rooms may request `direct` or `relay`; dedicated rooms must
|
||||
request `direct`. A dedicated relay advertisement, or a relay advertisement
|
||||
when relay service is unavailable, is rejected with `400 invalid_room`.
|
||||
|
||||
The `201` response includes the room, a secret `lease_token`, and an endpoint verification token.
|
||||
The host sends the verification token to the UDP rendezvous from its bound ENet socket. Rooms are
|
||||
|
|
@ -69,8 +77,18 @@ but TTL expiry remains authoritative for crashes and lost connectivity.
|
|||
|
||||
## `POST /v1/rooms/{room_id}/join-attempts`
|
||||
|
||||
Creates a short-lived traversal token for a public room. The joining game sends that token to the
|
||||
UDP rendezvous from the same ENet socket used for the gameplay connection.
|
||||
Creates a short-lived join capability for a public room. For a relay route, the joining game sends
|
||||
the capability to its allocated relay from the same ENet socket used for gameplay. The allocation
|
||||
then accepts traffic only from that authenticated client socket and the verified host endpoint.
|
||||
For an explicitly configured direct route, the capability retains the older rendezvous behavior.
|
||||
|
||||
The `201` response also contains a short-lived `route` with `transport`, `address`, `port`, and
|
||||
`ip_privacy`. For a relay room, these are the relay's public address and unique allocation port;
|
||||
the host endpoint is never returned. For a direct room, this is the only unauthenticated response
|
||||
that discloses the verified host endpoint, and it is issued only after an explicit Join. Responses
|
||||
are marked `Cache-Control: no-store`. Join issuance is limited per source address, per room,
|
||||
globally, and by concurrent pending count. A relay allocation failure returns
|
||||
`503 relay_unavailable`; it never falls back to direct.
|
||||
|
||||
## `GET /v1/rooms/{room_id}/join-attempts`
|
||||
|
||||
|
|
@ -109,10 +127,24 @@ live straywild session.
|
|||
|
||||
## Trust boundary
|
||||
|
||||
- The UDP rendezvous observation is authoritative for a room's public address and port.
|
||||
- The UDP rendezvous observation is authoritative for a room's private join address and port.
|
||||
- Public browse, presence, and invitation payloads never contain endpoints.
|
||||
- Endpoint-bearing join routes are short-lived and must never be shown, logged, or persisted by
|
||||
clients. Relay routes contain no peer endpoint.
|
||||
- `X-Forwarded-For` is honored only when the immediate peer belongs to an explicitly configured
|
||||
trusted proxy CIDR.
|
||||
- Lease tokens authorize update and deletion but are never included in public listings.
|
||||
- Friend capability channels are short-lived and reveal neither identity fingerprints nor a full
|
||||
social graph to the service.
|
||||
- The service is an ephemeral directory, not a source of gameplay or friendship authority.
|
||||
- The service emits no HTTP request/access log. It does not log raw addresses, ports,
|
||||
address-derived pseudonyms, request paths tied to rooms, names, payloads, headers, tokens,
|
||||
authentication material, or friendship capabilities. Unexpected request failures produce only
|
||||
a generic operational error without peer or request metadata.
|
||||
- Peer endpoints exist only in volatile room, join, abuse-limit, and relay state for as long as
|
||||
needed to provide the service. They are never written to an application log or database.
|
||||
- A production reverse proxy must have access logging disabled for all discovery routes. Default
|
||||
proxy logs commonly contain raw client addresses and violate this service's privacy policy.
|
||||
- The relay necessarily holds peer endpoints in volatile memory while an allocation is active.
|
||||
Allocations require a capability from the joining ENet socket, accept host traffic only from the
|
||||
verified endpoint, enforce traffic budgets, and expire when idle.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue