tickcli-js 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/remote.js CHANGED
@@ -18,9 +18,13 @@ import http from "node:http";
18
18
  import crypto from "node:crypto";
19
19
  import { fileURLToPath } from "node:url";
20
20
  import { WebSocketServer } from "ws";
21
- import { CLOSE, RoomHub } from "./hub.js";
22
- import { GuestPasses, Heartbeat, WS_OPTIONS, attach, clientAddress, fileSaves, gameHash } from "./node.js";
21
+ import { CLOSE, RoomHub, addressKey } from "./hub.js";
22
+ import { GuestPasses, Heartbeat, WS_OPTIONS, attach, clientAddress, fileSaves, gameHash, hardenServer } from "./node.js";
23
23
  const ID_RE = /^[A-Za-z0-9_-]{3,64}$/;
24
+ /** A deployment (found or not) is asked for again after this long; call forget(id) to make an edit count at once. */
25
+ export const LOOKUP_MS = 15_000;
26
+ /** Fresh lookups one client address (IPv6: /64) may cause per 10 s. */
27
+ export const LOOKUPS_PER_ADDRESS = 20;
24
28
  const GAME_RE = /^[A-Za-z0-9_-]{1,60}$/;
25
29
  const VER_RE = /^[A-Za-z0-9._-]{1,40}$/;
26
30
  const KEY_RE = /^[A-Za-z0-9_-]{22,64}$/;
@@ -95,9 +99,33 @@ export function createRemote(o) {
95
99
  const sources = { relay: src("relay"), room: src("room"), game: src("game") };
96
100
  const files = { relay: sources.relay, room: sources.room, game: sources.game, game3d: src("game3d") };
97
101
  const scope = (id) => `dep:${id}`;
98
- const lookup = async (id) => {
102
+ // Deployments are looked up at most once per LOOKUP_MS per id (found or not), and an address may cause at most LOOKUPS_PER_ADDRESS fresh lookups
103
+ // per 10 s: a flood of sockets or boot scripts with random ids costs a map hit, not a query on your table per request.
104
+ const seen = new Map(); // id -> when it was last looked up
105
+ const misses = new Map();
106
+ const lookupAllowed = (addr) => {
107
+ const k = addressKey(addr), now = Date.now();
108
+ let w = misses.get(k);
109
+ if (!w || now - w.at >= 10_000) {
110
+ if (misses.size >= 50_000)
111
+ for (const [x, v] of misses)
112
+ if (now - v.at >= 10_000)
113
+ misses.delete(x);
114
+ if (misses.size >= 50_000)
115
+ return false;
116
+ w = { at: now, n: 0 };
117
+ misses.set(k, w);
118
+ }
119
+ return ++w.n <= LOOKUPS_PER_ADDRESS;
120
+ };
121
+ const lookup = async (id, addr) => {
99
122
  if (!ID_RE.test(id))
100
123
  return null;
124
+ const at = seen.get(id);
125
+ if (at !== undefined && Date.now() - at < LOOKUP_MS)
126
+ return cache.get(id) ?? null;
127
+ if (!lookupAllowed(addr))
128
+ return cache.get(id) ?? null;
101
129
  let dep = null;
102
130
  try {
103
131
  dep = await o.deployment(id);
@@ -105,19 +133,24 @@ export function createRemote(o) {
105
133
  catch {
106
134
  dep = null;
107
135
  }
136
+ if (seen.size >= 100_000)
137
+ seen.clear();
138
+ seen.set(id, Date.now());
108
139
  if (dep && dep.id === id)
109
140
  cache.set(id, dep);
110
141
  else
111
142
  cache.delete(id);
112
143
  return dep && dep.id === id ? dep : null;
113
144
  };
145
+ const addrOf = (req) => (o.address ? o.address(req) : req.socket.remoteAddress || "?");
114
146
  // refused sockets are still accepted, then closed with a code the page shows (4001 is final: the page stops trying; 1013 busy: it retries)
115
147
  const closeWith = (req, socket, head, code, reason) => wss.handleUpgrade(req, socket, head, (ws) => ws.close(code, reason));
116
148
  return {
117
149
  scope,
118
150
  sockets: (id) => live.get(id) || 0,
119
151
  roomsPerScope: (sc) => (sc.startsWith("dep:") ? cache.get(sc.slice(4))?.caps?.rooms : undefined),
120
- revoke(id) { cache.delete(id); o.hub.closeScope(scope(id), "this game was turned off by its owner"); },
152
+ revoke(id) { cache.delete(id); seen.delete(id); o.hub.closeScope(scope(id), "this game was turned off by its owner"); },
153
+ forget(id) { cache.delete(id); seen.delete(id); },
121
154
  upgrade(req, socket, head) {
122
155
  const url = new URL(req.url || "/", "http://localhost");
123
156
  if (url.pathname !== path)
@@ -133,7 +166,12 @@ export function createRemote(o) {
133
166
  return true;
134
167
  }
135
168
  socket.on("error", () => { });
136
- void lookup(id).then((dep) => {
169
+ const addr = addrOf(req);
170
+ if (!o.hub.allowAddress(addr)) {
171
+ closeWith(req, socket, head, CLOSE.busy, "too many new connections, try again");
172
+ return true;
173
+ }
174
+ void lookup(id, addr).then((dep) => {
137
175
  if (socket.destroyed)
138
176
  return;
139
177
  if (!dep || dep.revoked)
@@ -152,7 +190,7 @@ export function createRemote(o) {
152
190
  else
153
191
  live.delete(id); });
154
192
  attach(ws, {
155
- hub: o.hub, heartbeat: o.heartbeat, address: o.address ? o.address(req) : req.socket.remoteAddress || "?",
193
+ hub: o.hub, heartbeat: o.heartbeat, address: addr, counted: true,
156
194
  // the guest key is the page's own random 128-bit value: unguessable, so nobody can take another player's seat; it names a seat in
157
195
  // this deployment only (the hub shows others a short HMAC of it, never the key)
158
196
  authenticate: (ticket) => typeof ticket === "string" && KEY_RE.test(ticket)
@@ -179,7 +217,7 @@ export function createRemote(o) {
179
217
  const b = /^\/c\/([^/]+)\.js$/.exec(url.pathname);
180
218
  if (!b)
181
219
  return false;
182
- void lookup(b[1]).then((dep) => {
220
+ void lookup(b[1], addrOf(req)).then((dep) => {
183
221
  if (!dep || dep.revoked)
184
222
  return js(404, `console.error(${JSON.stringify(`tickcli: no deployment ${b[1].slice(0, 64)} (unknown or turned off)`)});`);
185
223
  js(200, bootScript(dep.id, sources), "public, max-age=300");
@@ -196,12 +234,12 @@ export function createRemoteServer(o) {
196
234
  hub.start();
197
235
  const heartbeat = new Heartbeat();
198
236
  remote = createRemote({ hub, deployment: o.deployment, heartbeat, address: o.address ?? (o.trustProxy ? (req) => clientAddress(req, true) : undefined) });
199
- const server = http.createServer((req, res) => {
237
+ const server = hardenServer(http.createServer((req, res) => {
200
238
  if (remote.request(req, res))
201
239
  return;
202
240
  res.writeHead(404, { "Content-Type": "text/plain" });
203
241
  res.end("not found");
204
- });
242
+ }));
205
243
  server.on("upgrade", (req, socket, head) => { if (!remote.upgrade(req, socket, head))
206
244
  socket.destroy(); });
207
245
  const listen = (port = 8080, host) => new Promise((resolve, reject) => {
@@ -1 +1 @@
1
- {"version":3,"file":"remote.js","sourceRoot":"","sources":["../src/remote.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"remote.js","sourceRoot":"","sources":["../src/remote.ts"],"names":[],"mappings":"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"}
package/dist/serve.js CHANGED
@@ -18,7 +18,7 @@ import { createRequire } from "node:module";
18
18
  import { fileURLToPath } from "node:url";
19
19
  import { WebSocketServer } from "ws";
20
20
  import { RoomHub } from "./hub.js";
21
- import { GuestPasses, Heartbeat, WS_OPTIONS, attach, clientAddress, fileSaves, gameHash, sameSite } from "./node.js";
21
+ import { GuestPasses, Heartbeat, WS_OPTIONS, attach, clientAddress, fileSaves, gameHash, hardenServer, sameSite } from "./node.js";
22
22
  const CLIENT = fileURLToPath(new URL("../client/", import.meta.url));
23
23
  const PASS = "cw_pass";
24
24
  const SCOPE = "play";
@@ -171,7 +171,7 @@ export function createGameServer(o = {}) {
171
171
  return got;
172
172
  };
173
173
  const title = o.title ?? "tickcli games";
174
- const server = http.createServer((req, res) => {
174
+ const server = hardenServer(http.createServer((req, res) => {
175
175
  const url = new URL(req.url || "/", "http://localhost");
176
176
  const send = (code, type, body, headers = {}) => { res.writeHead(code, { "Content-Type": type, "Cache-Control": "no-store", "X-Content-Type-Options": "nosniff", ...headers }); res.end(body); };
177
177
  if (req.method !== "GET" && req.method !== "HEAD")
@@ -199,12 +199,15 @@ export function createGameServer(o = {}) {
199
199
  if (!passes.check(SCOPE, cookie(req, PASS)))
200
200
  headers["Set-Cookie"] = GuestPasses.cookie(PASS, passes.issue(SCOPE), "/", !!o.secure);
201
201
  return send(200, "text/html; charset=utf-8", playPage(html, g[1]), headers);
202
- });
202
+ }));
203
203
  server.on("upgrade", (req, socket, head) => {
204
204
  const url = new URL(req.url || "/", "http://localhost");
205
205
  const refuse = (code) => { socket.end(`HTTP/1.1 ${code} ${http.STATUS_CODES[code]}\r\nConnection: close\r\nContent-Length: 0\r\n\r\n`); };
206
206
  if (url.pathname !== "/room")
207
207
  return refuse(404);
208
+ const address = clientAddress(req, !!o.trustProxy);
209
+ if (!hub.allowAddress(address))
210
+ return refuse(429);
208
211
  if (!sameSite((n) => req.headers[n]))
209
212
  return refuse(403);
210
213
  const pass = passes.check(SCOPE, cookie(req, PASS));
@@ -215,7 +218,7 @@ export function createGameServer(o = {}) {
215
218
  if (!game)
216
219
  return refuse(404);
217
220
  const identity = { scope: `${SCOPE}:${name}`, game: game.hash, slot: name, who: { seat: `g:${pass}`, name: GuestPasses.defaultName(pass), guest: true } };
218
- wss.handleUpgrade(req, socket, head, (ws) => attach(ws, { hub, heartbeat, address: clientAddress(req, !!o.trustProxy), identity }));
221
+ wss.handleUpgrade(req, socket, head, (ws) => attach(ws, { hub, heartbeat, address, counted: true, identity }));
219
222
  });
220
223
  const listen = (port = 8080, host) => new Promise((resolve, reject) => {
221
224
  server.once("error", reject);
package/dist/serve.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"serve.js","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"serve.js","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tickcli-js",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Live rooms for browser games: one player's browser runs the rules, a small Node hub keeps the shared state, membership and order. No game code on the server.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -72,7 +72,7 @@
72
72
  },
73
73
  "peerDependencies": {
74
74
  "three": ">=0.171.0",
75
- "ws": "^8.18.0",
75
+ "ws": "^8.23.0",
76
76
  "phaser": ">=4.0.0",
77
77
  "pixi.js": ">=8.0.0"
78
78
  },
@@ -98,6 +98,6 @@
98
98
  "playwright": "1.64.0",
99
99
  "three": "0.186.1",
100
100
  "typescript": "5.9.3",
101
- "ws": "8.22.0"
101
+ "ws": "8.23.0"
102
102
  }
103
103
  }
package/src/hub.ts CHANGED
@@ -27,7 +27,8 @@ export interface Limits {
27
27
  maxRoomsPerScope: number; // per namespace (scope)
28
28
  maxConnections: number; // whole server, signed in or not
29
29
  maxPending: number; // whole server: sockets that have not proven who they are yet
30
- maxPerAddress: number; // open sockets per client address
30
+ maxPerAddress: number; // open sockets per client address (an IPv6 address counts by its /64: one home or server gets a whole /64)
31
+ connectsPerAddress: number; // new sockets per client address (IPv6: /64) per 10 s; over it: 1013 busy, before the server-wide acceptRate is spent
31
32
  joinsPerMinute: number; // per client address
32
33
  messageBytes: number; // one message
33
34
  playerStateBytes: number; // one player's state, as JSON
@@ -62,12 +63,23 @@ export interface Limits {
62
63
  }
63
64
 
64
65
  export const DEFAULT_LIMITS: Limits = {
65
- maxPlayers: 16, maxRooms: 500, maxRoomsPerScope: 50, maxConnections: 2000, maxPending: 200, maxPerAddress: 20, joinsPerMinute: 30,
66
+ maxPlayers: 16, maxRooms: 500, maxRoomsPerScope: 50, maxConnections: 2000, maxPending: 200, maxPerAddress: 20, connectsPerAddress: 40, joinsPerMinute: 30,
66
67
  messageBytes: 16 * 1024, playerStateBytes: 2048, sharedStateBytes: 64 * 1024, stateRate: 50, sharedRate: 20, actionRate: 5, timeRate: 2,
67
68
  pendingMs: 5000, seatHoldMs: 30_000, evictAfterMs: 10_000, awayHoldMs: 300_000, hostSilenceMs: 5000, silentMs: 15_000, acceptRate: 200, roomOutBytes: 250 * 1024, maxOutMbit: 100, actionTimeoutMs: 5000, slowBytes: 64 * 1024, dropBytes: 256 * 1024, rateBytes: 16 * 1024, rateUpMs: 10_000, listRate: 1, idleMs: 15 * 60_000, idleWarnMs: 60_000, listIdleMs: 5 * 60_000, tickMs: 50,
68
69
  profileBytes: 16 * 1024, profileEveryMs: 3000, worldEveryMs: 5000, saveDays: 90,
69
70
  };
70
71
 
72
+ /** The key one client is counted by: an IPv4 address as is, an IPv6 address by its first 64 bits (a home, phone or server is handed a whole /64,
73
+ * so per-address limits on full IPv6 addresses would not hold anyone). IPv4-mapped IPv6 counts as the IPv4 address. */
74
+ export function addressKey(addr: string): string {
75
+ const a = String(addr || "?").toLowerCase().replace(/^::ffff:(?=\d+\.)/, "").replace(/%.*$/, "");
76
+ if (!a.includes(":")) return a;
77
+ const [head, tail = ""] = a.split("::");
78
+ const h = head ? head.split(":") : [], t = tail ? tail.split(":") : [];
79
+ const groups = a.includes("::") ? [...h, ...Array(Math.max(0, 8 - h.length - t.length)).fill("0"), ...t] : h;
80
+ return `${groups.slice(0, 4).map((g) => (g || "0").replace(/^0+(?=.)/, "")).join(":")}::/64`;
81
+ }
82
+
71
83
  /** One open socket, as the hub sees it. */
72
84
  export interface Conn {
73
85
  send(data: string): void;
@@ -486,6 +498,7 @@ export class RoomHub {
486
498
  private sessions = new Set<Session>();
487
499
  pending = 0;
488
500
  private perAddr = new Map<string, number>();
501
+ private addrHits = new Map<string, { at: number; n: number }>();
489
502
  private joins = new Map<string, number[]>();
490
503
  private refused: Record<string, number> = {};
491
504
  private timer: ReturnType<typeof setInterval> | null = null;
@@ -551,16 +564,20 @@ export class RoomHub {
551
564
  private count(what: string, n = 1) { this.counts[what] = (this.counts[what] || 0) + n; }
552
565
 
553
566
  /** A new socket. Null = refused (the caller closes it with the code given). */
554
- connect(conn: Conn, addr: string): Session | { refused: number; reason: string } {
567
+ /** `counted`: the adapter already spent this socket's allowAddress before its upgrade, so it is not counted twice. */
568
+ connect(conn: Conn, address: string, o: { counted?: boolean } = {}): Session | { refused: number; reason: string } {
555
569
  const L = this.limits;
570
+ const addr = addressKey(address);
556
571
  if (this.closing) return { refused: CLOSE.restart, reason: "server restarting" };
557
572
  if (this.sessions.size >= L.maxConnections) { this.refuse("connections"); return { refused: CLOSE.full, reason: "server is full" }; }
573
+ // one address first: a single client flooding new sockets is cut here and never spends the server-wide budgets below that everyone shares
574
+ if ((this.perAddr.get(addr) || 0) >= L.maxPerAddress) { this.refuse("address"); return { refused: CLOSE.tooFast, reason: "too many connections" }; }
575
+ if (!o.counted && !this.allowAddress(addr)) { this.refuse("address_rate"); return { refused: CLOSE.busy, reason: "too many new connections, try again" }; }
558
576
  // busy (not full): the page tries again with its normal backoff, so a reconnect wave after a restart spreads out instead of ending on a "full" screen
559
577
  if (this.pending >= L.maxPending) { this.refuse("pending"); return { refused: CLOSE.busy, reason: "server is busy, try again" }; }
560
578
  const now = this.now();
561
579
  if (now - this.acceptAt >= 1000) { this.acceptAt = now; this.accepted = 0; }
562
580
  if (++this.accepted > L.acceptRate) { this.refuse("accept_rate"); return { refused: CLOSE.busy, reason: "server is busy, try again" }; }
563
- if ((this.perAddr.get(addr) || 0) >= L.maxPerAddress) { this.refuse("address"); return { refused: CLOSE.tooFast, reason: "too many connections" }; }
564
581
  const s = new Session(this, conn, addr);
565
582
  this.sessions.add(s);
566
583
  this.pending++;
@@ -568,6 +585,20 @@ export class RoomHub {
568
585
  return s;
569
586
  }
570
587
 
588
+ /** New-socket budget of one address (addressKey), connectsPerAddress per 10 s. Adapters may call it before costly work on an upgrade (a lookup):
589
+ * false = refuse now. The window map is pruned when it grows, so random addresses cannot grow it without end. */
590
+ allowAddress(address: string): boolean {
591
+ const key = addressKey(address), now = this.now();
592
+ let w = this.addrHits.get(key);
593
+ if (!w || now - w.at >= 10_000) {
594
+ if (this.addrHits.size >= 50_000) for (const [k, v] of this.addrHits) if (now - v.at >= 10_000) this.addrHits.delete(k);
595
+ if (this.addrHits.size >= 50_000) return false; // 50,000 addresses inside 10 s: refuse newcomers until the window turns
596
+ w = { at: now, n: 0 };
597
+ this.addrHits.set(key, w);
598
+ }
599
+ return ++w.n <= this.limits.connectsPerAddress;
600
+ }
601
+
571
602
  /** Meter: `n` copies of a text of `len` bytes (UTF-8, as on the wire) went out (to one room's sockets when given). */
572
603
  sent(len: number, n: number, room?: Room | null) {
573
604
  this.meter.framesOut += n; this.meter.bytesOut += len * n;
package/src/node.ts CHANGED
@@ -7,6 +7,7 @@
7
7
  // passes - for anonymous visitors: the app sets a pass cookie (HttpOnly, SameSite=Strict, scoped to one path) and checks it at the upgrade.
8
8
  // Plus: the Origin header must be present and name the site itself (sameSite()).
9
9
  import crypto from "node:crypto";
10
+ import type http from "node:http";
10
11
  import type { WebSocket } from "ws";
11
12
  import fs from "node:fs";
12
13
  import path from "node:path";
@@ -141,6 +142,8 @@ export interface Identity {
141
142
 
142
143
  export interface SocketOptions {
143
144
  hub: RoomHub;
145
+ /** true when the upgrade handler already called hub.allowAddress for this socket */
146
+ counted?: boolean;
144
147
  heartbeat?: Heartbeat;
145
148
  /** client address, for the per-address caps (after your trusted-proxy rule) */
146
149
  address: string;
@@ -162,7 +165,7 @@ export function socketEvents(o: SocketOptions) {
162
165
  open(ws: WebSocket) {
163
166
  raw = ws;
164
167
  o.heartbeat?.add(ws);
165
- const r = o.hub.connect(connOf(ws), o.address);
168
+ const r = o.hub.connect(connOf(ws), o.address, { counted: o.counted });
166
169
  if ("refused" in r) { ws.close(r.refused, r.reason); return; }
167
170
  session = r;
168
171
  if (o.identity) session.identify(o.identity.scope, o.identity.game, o.identity.who, o.identity.slot);
@@ -201,6 +204,16 @@ export function attach(ws: WebSocket, o: SocketOptions) {
201
204
  ws.on("error", () => { /* close follows */ });
202
205
  }
203
206
 
207
+ /** Tighter HTTP timeouts than Node's defaults (headers 60 s, whole request 300 s, 2000 headers) for a server that only serves small pages and
208
+ * socket upgrades: a client that sends its request headers slowly (slowloris) is cut after `headersMs`, an idle keep-alive after 5 s. */
209
+ export function hardenServer<S extends http.Server>(server: S, o: { headersMs?: number; requestMs?: number; keepAliveMs?: number; maxHeaders?: number } = {}): S {
210
+ server.headersTimeout = o.headersMs ?? 10_000;
211
+ server.requestTimeout = o.requestMs ?? 15_000;
212
+ server.keepAliveTimeout = o.keepAliveMs ?? 5_000;
213
+ server.maxHeadersCount = o.maxHeaders ?? 100;
214
+ return server;
215
+ }
216
+
204
217
  /** Options for a ws WebSocketServer that fit the hub: no own size default of 100 MiB, no compression, no client list (the hub tracks sockets). */
205
218
  export const WS_OPTIONS = { noServer: true, maxPayload: 16 * 1024, perMessageDeflate: false, clientTracking: false } as const;
206
219
 
package/src/remote.ts CHANGED
@@ -19,8 +19,8 @@ import crypto from "node:crypto";
19
19
  import type { Duplex } from "node:stream";
20
20
  import { fileURLToPath } from "node:url";
21
21
  import { WebSocketServer, type WebSocket } from "ws";
22
- import { CLOSE, RoomHub, type Limits, type SavePort } from "./hub.ts";
23
- import { GuestPasses, Heartbeat, WS_OPTIONS, attach, clientAddress, fileSaves, gameHash } from "./node.ts";
22
+ import { CLOSE, RoomHub, addressKey, type Limits, type SavePort } from "./hub.ts";
23
+ import { GuestPasses, Heartbeat, WS_OPTIONS, attach, clientAddress, fileSaves, gameHash, hardenServer } from "./node.ts";
24
24
 
25
25
  export interface Deployment {
26
26
  /** public id, as in the page's script tag: letters, digits, "_" and "-", 3 to 64 */
@@ -59,6 +59,8 @@ export interface Remote {
59
59
  request(req: http.IncomingMessage, res: http.ServerResponse): boolean;
60
60
  /** Turn a deployment off now: its open rooms close (saves are written first) and its cached settings are dropped. */
61
61
  revoke(id: string): void;
62
+ /** Drop the cached settings of one deployment (after its sites or caps changed) without closing its rooms. Unchanged ones refresh every LOOKUP_MS. */
63
+ forget(id: string): void;
62
64
  /** The hub namespace of a deployment (for hub.scopeStats, hub.closeScope). */
63
65
  scope(id: string): string;
64
66
  /** The rooms cap the hub should use for a namespace (pass to new RoomHub({ roomsPerScope })). */
@@ -68,6 +70,10 @@ export interface Remote {
68
70
  }
69
71
 
70
72
  const ID_RE = /^[A-Za-z0-9_-]{3,64}$/;
73
+ /** A deployment (found or not) is asked for again after this long; call forget(id) to make an edit count at once. */
74
+ export const LOOKUP_MS = 15_000;
75
+ /** Fresh lookups one client address (IPv6: /64) may cause per 10 s. */
76
+ export const LOOKUPS_PER_ADDRESS = 20;
71
77
  const GAME_RE = /^[A-Za-z0-9_-]{1,60}$/;
72
78
  const VER_RE = /^[A-Za-z0-9._-]{1,40}$/;
73
79
  const KEY_RE = /^[A-Za-z0-9_-]{22,64}$/;
@@ -134,13 +140,33 @@ export function createRemote(o: RemoteOptions): Remote {
134
140
  const sources = { relay: src("relay"), room: src("room"), game: src("game") };
135
141
  const files: Record<string, string> = { relay: sources.relay, room: sources.room, game: sources.game, game3d: src("game3d") };
136
142
  const scope = (id: string) => `dep:${id}`;
137
- const lookup = async (id: string) => {
143
+ // Deployments are looked up at most once per LOOKUP_MS per id (found or not), and an address may cause at most LOOKUPS_PER_ADDRESS fresh lookups
144
+ // per 10 s: a flood of sockets or boot scripts with random ids costs a map hit, not a query on your table per request.
145
+ const seen = new Map<string, number>(); // id -> when it was last looked up
146
+ const misses = new Map<string, { at: number; n: number }>();
147
+ const lookupAllowed = (addr: string) => {
148
+ const k = addressKey(addr), now = Date.now();
149
+ let w = misses.get(k);
150
+ if (!w || now - w.at >= 10_000) {
151
+ if (misses.size >= 50_000) for (const [x, v] of misses) if (now - v.at >= 10_000) misses.delete(x);
152
+ if (misses.size >= 50_000) return false;
153
+ w = { at: now, n: 0 }; misses.set(k, w);
154
+ }
155
+ return ++w.n <= LOOKUPS_PER_ADDRESS;
156
+ };
157
+ const lookup = async (id: string, addr: string) => {
138
158
  if (!ID_RE.test(id)) return null;
159
+ const at = seen.get(id);
160
+ if (at !== undefined && Date.now() - at < LOOKUP_MS) return cache.get(id) ?? null;
161
+ if (!lookupAllowed(addr)) return cache.get(id) ?? null;
139
162
  let dep: Deployment | null | undefined = null;
140
163
  try { dep = await o.deployment(id); } catch { dep = null; }
164
+ if (seen.size >= 100_000) seen.clear();
165
+ seen.set(id, Date.now());
141
166
  if (dep && dep.id === id) cache.set(id, dep); else cache.delete(id);
142
167
  return dep && dep.id === id ? dep : null;
143
168
  };
169
+ const addrOf = (req: http.IncomingMessage) => (o.address ? o.address(req) : req.socket.remoteAddress || "?");
144
170
  // refused sockets are still accepted, then closed with a code the page shows (4001 is final: the page stops trying; 1013 busy: it retries)
145
171
  const closeWith = (req: http.IncomingMessage, socket: Duplex, head: Buffer, code: number, reason: string) =>
146
172
  wss.handleUpgrade(req, socket, head, (ws: WebSocket) => ws.close(code, reason));
@@ -149,7 +175,8 @@ export function createRemote(o: RemoteOptions): Remote {
149
175
  scope,
150
176
  sockets: (id) => live.get(id) || 0,
151
177
  roomsPerScope: (sc) => (sc.startsWith("dep:") ? cache.get(sc.slice(4))?.caps?.rooms : undefined),
152
- revoke(id) { cache.delete(id); o.hub.closeScope(scope(id), "this game was turned off by its owner"); },
178
+ revoke(id) { cache.delete(id); seen.delete(id); o.hub.closeScope(scope(id), "this game was turned off by its owner"); },
179
+ forget(id) { cache.delete(id); seen.delete(id); },
153
180
 
154
181
  upgrade(req, socket, head) {
155
182
  const url = new URL(req.url || "/", "http://localhost");
@@ -159,7 +186,9 @@ export function createRemote(o: RemoteOptions): Remote {
159
186
  const id = url.searchParams.get("d") || "", game = url.searchParams.get("game") || "", ver = url.searchParams.get("v") || "1";
160
187
  if (!GAME_RE.test(game) || !VER_RE.test(ver)) { closeWith(req, socket, head, CLOSE.badMessage, "bad game name or version"); return true; }
161
188
  socket.on("error", () => { /* closed early */ });
162
- void lookup(id).then((dep) => {
189
+ const addr = addrOf(req);
190
+ if (!o.hub.allowAddress(addr)) { closeWith(req, socket, head, CLOSE.busy, "too many new connections, try again"); return true; }
191
+ void lookup(id, addr).then((dep) => {
163
192
  if (socket.destroyed) return;
164
193
  if (!dep || dep.revoked) return closeWith(req, socket, head, CLOSE.notAllowed, "this game's deployment is unknown or turned off");
165
194
  if (!originAllowed(dep, origin)) return closeWith(req, socket, head, CLOSE.notAllowed, `this site is not allowed for deployment ${id}`);
@@ -170,7 +199,7 @@ export function createRemote(o: RemoteOptions): Remote {
170
199
  live.set(id, (live.get(id) || 0) + 1);
171
200
  ws.on("close", () => { const left = (live.get(id) || 1) - 1; if (left > 0) live.set(id, left); else live.delete(id); });
172
201
  attach(ws, {
173
- hub: o.hub, heartbeat: o.heartbeat, address: o.address ? o.address(req) : req.socket.remoteAddress || "?",
202
+ hub: o.hub, heartbeat: o.heartbeat, address: addr, counted: true,
174
203
  // the guest key is the page's own random 128-bit value: unguessable, so nobody can take another player's seat; it names a seat in
175
204
  // this deployment only (the hub shows others a short HMAC of it, never the key)
176
205
  authenticate: (ticket) => typeof ticket === "string" && KEY_RE.test(ticket)
@@ -193,7 +222,7 @@ export function createRemote(o: RemoteOptions): Remote {
193
222
  if (c) { js(200, files[c[1]], "public, max-age=300"); return true; }
194
223
  const b = /^\/c\/([^/]+)\.js$/.exec(url.pathname);
195
224
  if (!b) return false;
196
- void lookup(b[1]).then((dep) => {
225
+ void lookup(b[1], addrOf(req)).then((dep) => {
197
226
  if (!dep || dep.revoked) return js(404, `console.error(${JSON.stringify(`tickcli: no deployment ${b[1].slice(0, 64)} (unknown or turned off)`)});`);
198
227
  js(200, bootScript(dep.id, sources), "public, max-age=300");
199
228
  });
@@ -222,10 +251,10 @@ export function createRemoteServer(o: RemoteServerOptions) {
222
251
  hub.start();
223
252
  const heartbeat = new Heartbeat();
224
253
  remote = createRemote({ hub, deployment: o.deployment, heartbeat, address: o.address ?? (o.trustProxy ? (req) => clientAddress(req, true) : undefined) });
225
- const server = http.createServer((req, res) => {
254
+ const server = hardenServer(http.createServer((req, res) => {
226
255
  if (remote!.request(req, res)) return;
227
256
  res.writeHead(404, { "Content-Type": "text/plain" }); res.end("not found");
228
- });
257
+ }));
229
258
  server.on("upgrade", (req, socket, head) => { if (!remote!.upgrade(req, socket, head)) socket.destroy(); });
230
259
  const listen = (port = 8080, host?: string) => new Promise<string>((resolve, reject) => {
231
260
  server.once("error", reject);
package/src/serve.ts CHANGED
@@ -18,7 +18,7 @@ import { createRequire } from "node:module";
18
18
  import { fileURLToPath } from "node:url";
19
19
  import { WebSocketServer } from "ws";
20
20
  import { RoomHub, type Limits, type SavePort } from "./hub.ts";
21
- import { GuestPasses, Heartbeat, WS_OPTIONS, attach, clientAddress, fileSaves, gameHash, sameSite } from "./node.ts";
21
+ import { GuestPasses, Heartbeat, WS_OPTIONS, attach, clientAddress, fileSaves, gameHash, hardenServer, sameSite } from "./node.ts";
22
22
 
23
23
  export interface GameServerOptions {
24
24
  /** Folder of games, one .html file each (names: letters, digits, "-" and "_"). Default: the current folder. */
@@ -172,7 +172,7 @@ export function createGameServer(o: GameServerOptions = {}): GameServer {
172
172
  };
173
173
  const title = o.title ?? "tickcli games";
174
174
 
175
- const server = http.createServer((req, res) => {
175
+ const server = hardenServer(http.createServer((req, res) => {
176
176
  const url = new URL(req.url || "/", "http://localhost");
177
177
  const send = (code: number, type: string, body: string, headers: Record<string, string> = {}) => { res.writeHead(code, { "Content-Type": type, "Cache-Control": "no-store", "X-Content-Type-Options": "nosniff", ...headers }); res.end(body); };
178
178
  if (req.method !== "GET" && req.method !== "HEAD") return send(405, "text/plain", "method not allowed");
@@ -195,12 +195,14 @@ export function createGameServer(o: GameServerOptions = {}): GameServer {
195
195
  const headers: Record<string, string> = { "Content-Security-Policy": `default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'unsafe-inline'; img-src data: blob:; connect-src 'self'${wsOrigins(req)}; frame-ancestors 'none'` };
196
196
  if (!passes.check(SCOPE, cookie(req, PASS))) headers["Set-Cookie"] = GuestPasses.cookie(PASS, passes.issue(SCOPE), "/", !!o.secure);
197
197
  return send(200, "text/html; charset=utf-8", playPage(html, g![1]), headers);
198
- });
198
+ }));
199
199
 
200
200
  server.on("upgrade", (req, socket, head) => {
201
201
  const url = new URL(req.url || "/", "http://localhost");
202
202
  const refuse = (code: number) => { socket.end(`HTTP/1.1 ${code} ${http.STATUS_CODES[code]}\r\nConnection: close\r\nContent-Length: 0\r\n\r\n`); };
203
203
  if (url.pathname !== "/room") return refuse(404);
204
+ const address = clientAddress(req, !!o.trustProxy);
205
+ if (!hub.allowAddress(address)) return refuse(429);
204
206
  if (!sameSite((n) => req.headers[n] as string | undefined)) return refuse(403);
205
207
  const pass = passes.check(SCOPE, cookie(req, PASS));
206
208
  if (!pass) return refuse(403);
@@ -208,7 +210,7 @@ export function createGameServer(o: GameServerOptions = {}): GameServer {
208
210
  const game = read(name);
209
211
  if (!game) return refuse(404);
210
212
  const identity = { scope: `${SCOPE}:${name}`, game: game.hash, slot: name, who: { seat: `g:${pass}`, name: GuestPasses.defaultName(pass), guest: true } };
211
- wss.handleUpgrade(req, socket, head, (ws) => attach(ws, { hub, heartbeat, address: clientAddress(req, !!o.trustProxy), identity }));
213
+ wss.handleUpgrade(req, socket, head, (ws) => attach(ws, { hub, heartbeat, address, counted: true, identity }));
212
214
  });
213
215
 
214
216
  const listen = (port = 8080, host?: string) => new Promise<string>((resolve, reject) => {