Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 33 additions & 6 deletions lib/sender.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

const net = require('net');
const tls = require('tls');
const { randomFillSync } = require('crypto');
const { randomBytes } = require('crypto');

const PerMessageDeflate = require('./permessage-deflate');
const { EMPTY_BUFFER } = require('./constants');
Expand All @@ -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.
*/
Expand Down Expand Up @@ -81,13 +97,24 @@ class Sender {

if (!options.mask) return [target, data];

randomFillSync(mask, 0, 4);
Comment thread
ronag marked this conversation as resolved.
if (randomPool.length - randomPoolIdx < 4) {
randomPool = randomBytes(32);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not convinced this is much better than the status quo. It would only take 8 WebSocket each sending a single message to empty the pool and there is a new Buffer allocation every time.

@ronag ronag Dec 17, 2021

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just the fallback path. We shouldn't hit this often, if at all.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you are misunderstanding something here...?

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);
Expand Down