backend: add gateway ratelimit
This commit is contained in:
parent
2f19cb211d
commit
9c9f764e6d
3 changed files with 12 additions and 2 deletions
|
@ -12,4 +12,5 @@ export const gatewayErrors = {
|
||||||
BAD_AUTH: { code: 4002, message: "Bad authentication" },
|
BAD_AUTH: { code: 4002, message: "Bad authentication" },
|
||||||
AUTHENTICATION_TIMEOUT: { code: 4003, message: "Authentication timeout" },
|
AUTHENTICATION_TIMEOUT: { code: 4003, message: "Authentication timeout" },
|
||||||
NO_PING: { code: 4004, message: "No ping" },
|
NO_PING: { code: 4004, message: "No ping" },
|
||||||
|
FLOODING: { code: 4005, message: "Flooding (exceeded maximum messages per batch)" },
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { GatewayPayloadType } from "./gatewaypayloadtype";
|
||||||
|
|
||||||
const GATEWAY_BATCH_INTERVAL = 50000;
|
const GATEWAY_BATCH_INTERVAL = 50000;
|
||||||
const GATEWAY_PING_INTERVAL = 40000;
|
const GATEWAY_PING_INTERVAL = 40000;
|
||||||
|
const MAX_CLIENT_MESSAGES_PER_BATCH = 6; // TODO: how well does this work for weak connections?
|
||||||
|
|
||||||
// mapping between a dispatch id and a websocket client
|
// mapping between a dispatch id and a websocket client
|
||||||
const dispatchChannels = new Map<string, Set<WebSocket>>();
|
const dispatchChannels = new Map<string, Set<WebSocket>>();
|
||||||
|
@ -128,6 +129,7 @@ export default function(server: Server) {
|
||||||
if (!e.state.alive) {
|
if (!e.state.alive) {
|
||||||
return closeWithError(e, gatewayErrors.NO_PING);
|
return closeWithError(e, gatewayErrors.NO_PING);
|
||||||
}
|
}
|
||||||
|
e.state.messagesSinceLastCheck = 0;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, GATEWAY_BATCH_INTERVAL);
|
}, GATEWAY_BATCH_INTERVAL);
|
||||||
|
@ -144,7 +146,8 @@ export default function(server: Server) {
|
||||||
alive: false,
|
alive: false,
|
||||||
ready: false,
|
ready: false,
|
||||||
lastAliveCheck: performance.now(),
|
lastAliveCheck: performance.now(),
|
||||||
dispatchChannels: new Set()
|
dispatchChannels: new Set(),
|
||||||
|
messagesSinceLastCheck: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
sendPayload(ws, {
|
sendPayload(ws, {
|
||||||
|
@ -163,6 +166,11 @@ export default function(server: Server) {
|
||||||
return closeWithBadPayload(ws, "Binary messages are not supported");
|
return closeWithBadPayload(ws, "Binary messages are not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ws.state.messagesSinceLastCheck++;
|
||||||
|
if (ws.state.messagesSinceLastCheck > MAX_CLIENT_MESSAGES_PER_BATCH) {
|
||||||
|
return closeWithError(ws, gatewayErrors.FLOODING);
|
||||||
|
}
|
||||||
|
|
||||||
const payload = ensureFormattedGatewayPayload(parseJsonOrNull(rawData.toString()));
|
const payload = ensureFormattedGatewayPayload(parseJsonOrNull(rawData.toString()));
|
||||||
if (!payload) {
|
if (!payload) {
|
||||||
return closeWithBadPayload(ws, "Invalid JSON or message does not match schema");
|
return closeWithBadPayload(ws, "Invalid JSON or message does not match schema");
|
||||||
|
|
3
src/types/gatewayclientstate.d.ts
vendored
3
src/types/gatewayclientstate.d.ts
vendored
|
@ -3,5 +3,6 @@ interface GatewayClientState {
|
||||||
ready: boolean,
|
ready: boolean,
|
||||||
alive: boolean,
|
alive: boolean,
|
||||||
lastAliveCheck: number,
|
lastAliveCheck: number,
|
||||||
dispatchChannels: Set<string>
|
dispatchChannels: Set<string>,
|
||||||
|
messagesSinceLastCheck: number
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue