From 79eae6faf5d78bf6d26a66c2c2e9caa6fe08e863 Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Fri, 17 Dec 2021 10:21:58 +0100 Subject: [PATCH 1/2] perf: use a random pool --- lib/random-util.js | 39 +++++++++++++++++++++++++++++++++++++++ lib/sender.js | 4 ++-- 2 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 lib/random-util.js diff --git a/lib/random-util.js b/lib/random-util.js new file mode 100644 index 000000000..1039217b2 --- /dev/null +++ b/lib/random-util.js @@ -0,0 +1,39 @@ +'use strict'; + +const RANDOM_POOL_SIZE = 8192; +const RANDOM_POOL_REFRESH = 1024; + +let randomPool = Buffer.alloc(RANDOM_POOL_SIZE); +let randomPoolIdx = RANDOM_POOL_SIZE; + +function onRandomBytes (err, buf) { + randomPending = false; + if (!err) { + randomPool = buf; + randomPoolIdx = 0; + } +} + +let randomPending = true; +crypto.randomBytes(RANDOM_POOL_SIZE, onRandomBytes); + +function randomFillMask (buffer) { + if (RANDOM_POOL_SIZE - randomPoolIdx < 4) { + // assert(randomPending) + return crypto.randomFillSync(buffer, offset, size); + } + + buffer[0] = randomPool[randomPoolIdx++]; + buffer[1] = randomPool[randomPoolIdx++]; + buffer[2] = randomPool[randomPoolIdx++]; + buffer[3] = randomPool[randomPoolIdx++]; + + if (RANDOM_POOL_SIZE - randomPoolIdx < RANDOM_POOL_REFRESH && !randomPending) { + randomPending = true; + crypto.randomBytes(RANDOM_POOL_SIZE, onRandomBytes); + } + + return buffer; +} + +module.exports = { randomFillMask }; diff --git a/lib/sender.js b/lib/sender.js index 4490a623b..082237b91 100644 --- a/lib/sender.js +++ b/lib/sender.js @@ -4,7 +4,7 @@ const net = require('net'); const tls = require('tls'); -const { randomFillSync } = require('crypto'); +const { randomFillMask } = require('./random-util'); const PerMessageDeflate = require('./permessage-deflate'); const { EMPTY_BUFFER } = require('./constants'); @@ -81,7 +81,7 @@ class Sender { if (!options.mask) return [target, data]; - randomFillSync(mask, 0, 4); + randomFillMask(mask); target[1] |= 0x80; target[offset - 4] = mask[0]; From 238a7230e89662e269409c5feb7d1c2f644b6640 Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Fri, 17 Dec 2021 11:25:21 +0100 Subject: [PATCH 2/2] fixup --- lib/random-util.js | 39 --------------------------------------- lib/sender.js | 39 +++++++++++++++++++++++++++++++++------ 2 files changed, 33 insertions(+), 45 deletions(-) delete mode 100644 lib/random-util.js diff --git a/lib/random-util.js b/lib/random-util.js deleted file mode 100644 index 1039217b2..000000000 --- a/lib/random-util.js +++ /dev/null @@ -1,39 +0,0 @@ -'use strict'; - -const RANDOM_POOL_SIZE = 8192; -const RANDOM_POOL_REFRESH = 1024; - -let randomPool = Buffer.alloc(RANDOM_POOL_SIZE); -let randomPoolIdx = RANDOM_POOL_SIZE; - -function onRandomBytes (err, buf) { - randomPending = false; - if (!err) { - randomPool = buf; - randomPoolIdx = 0; - } -} - -let randomPending = true; -crypto.randomBytes(RANDOM_POOL_SIZE, onRandomBytes); - -function randomFillMask (buffer) { - if (RANDOM_POOL_SIZE - randomPoolIdx < 4) { - // assert(randomPending) - return crypto.randomFillSync(buffer, offset, size); - } - - buffer[0] = randomPool[randomPoolIdx++]; - buffer[1] = randomPool[randomPoolIdx++]; - buffer[2] = randomPool[randomPoolIdx++]; - buffer[3] = randomPool[randomPoolIdx++]; - - if (RANDOM_POOL_SIZE - randomPoolIdx < RANDOM_POOL_REFRESH && !randomPending) { - randomPending = true; - crypto.randomBytes(RANDOM_POOL_SIZE, onRandomBytes); - } - - return buffer; -} - -module.exports = { randomFillMask }; diff --git a/lib/sender.js b/lib/sender.js index 082237b91..25df14cde 100644 --- a/lib/sender.js +++ b/lib/sender.js @@ -4,7 +4,7 @@ const net = require('net'); const tls = require('tls'); -const { randomFillMask } = require('./random-util'); +const { randomBytes } = require('crypto'); const PerMessageDeflate = require('./permessage-deflate'); const { EMPTY_BUFFER } = require('./constants'); @@ -13,6 +13,22 @@ const { mask: applyMask, toBuffer } = require('./buffer-util'); const mask = Buffer.alloc(4); +const RANDOM_POOL_SIZE = 8192; +const RANDOM_POOL_REFRESH = 1024; + +let randomPool = Buffer.alloc(0); +let randomPoolIdx = 0; +let randomPending = true; + +function onRandomBytes(err, buf) { + randomPending = false; + if (!err) { + randomPool = buf; + randomPoolIdx = 0; + } +} +randomBytes(RANDOM_POOL_SIZE, onRandomBytes); + /** * HyBi Sender implementation. */ @@ -81,13 +97,24 @@ class Sender { if (!options.mask) return [target, data]; - randomFillMask(mask); + if (randomPool.length - randomPoolIdx < 4) { + randomPool = randomBytes(32); + randomPoolIdx = 0; + } target[1] |= 0x80; - target[offset - 4] = mask[0]; - target[offset - 3] = mask[1]; - target[offset - 2] = mask[2]; - target[offset - 1] = mask[3]; + target[offset - 4] = mask[0] = randomPool[randomPoolIdx++]; + target[offset - 3] = mask[1] = randomPool[randomPoolIdx++]; + target[offset - 2] = mask[2] = randomPool[randomPoolIdx++]; + target[offset - 1] = mask[3] = randomPool[randomPoolIdx++]; + + if ( + !randomPending && + randomPool.length - randomPoolIdx < RANDOM_POOL_REFRESH + ) { + randomPending = true; + randomBytes(RANDOM_POOL_SIZE, onRandomBytes); + } if (merge) { applyMask(data, mask, target, offset, data.length);