improve theoretically captcha DDoS handling

This commit is contained in:
HF 2022-06-21 03:27:22 +02:00
parent 038cb8b6e1
commit 230cf8811a
2 changed files with 19 additions and 16 deletions

View File

@ -6,7 +6,7 @@ import { Worker } from 'worker_threads';
import logger from './logger'; import logger from './logger';
const MAX_WAIT = 20 * 1000; const MAX_WAIT = 30 * 1000;
/* /*
* worker thread * worker thread
@ -17,7 +17,7 @@ const worker = new Worker('./workers/captchaloader.js');
* queue of captcha-generation tasks * queue of captcha-generation tasks
* [[ timestamp, callbackFunction ],...] * [[ timestamp, callbackFunction ],...]
*/ */
let captchaQueue = []; const captchaQueue = [];
/* /*
* generate a captcha in the worker thread * generate a captcha in the worker thread
@ -36,30 +36,33 @@ function requestCaptcha(cb) {
* answer of worker thread * answer of worker thread
*/ */
worker.on('message', (msg) => { worker.on('message', (msg) => {
const task = captchaQueue.shift(); while (captchaQueue.length) {
task[1](...msg); const task = captchaQueue.shift();
try {
task[1](...msg);
return;
} catch {
// continue
}
}
}); });
/* /*
* checks queue of captcha requests for stale * clear requests if queue can't keep up
* unanswered requests
*/ */
function clearOldQueue() { function clearOldQueue() {
const now = Date.now(); const now = Date.now();
captchaQueue = captchaQueue.filter((task) => { if (captchaQueue.length
if (now - task[0] > MAX_WAIT) { && now - captchaQueue[0][0] > MAX_WAIT) {
logger.warn( logger.warn('Captchas: Queue can not keep up!');
'Captchas: Thread took longer than 30s to generate captcha', captchaQueue.forEach((task) => {
);
try { try {
task[1]('TIMEOUT'); task[1]('TIMEOUT');
} catch { } catch {
// nothing // nothing
} }
return false; });
} }
return true;
});
} }
setInterval(clearOldQueue, MAX_WAIT); setInterval(clearOldQueue, MAX_WAIT);

View File

@ -13,7 +13,7 @@ export default (req, res) => {
requestCaptcha((err, text, data, id) => { requestCaptcha((err, text, data, id) => {
if (res.writableEnded) { if (res.writableEnded) {
return; throw new Error('ENOR');
} }
if (err) { if (err) {