From 956fdd8ca891de7f1607a8ae7b8eefc652871c41 Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Mon, 8 Feb 2021 18:23:29 -0800 Subject: [PATCH] Fixed random bias. --- common.js | 10 ++++++++-- multiserver.js | 3 ++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/common.js b/common.js index 49e37084..97eccca0 100644 --- a/common.js +++ b/common.js @@ -95,8 +95,14 @@ module.exports.data2blob = function (data) { return blob; }; -// Generate random numbers -module.exports.random = function (max) { (require('crypto').randomBytes(4).readUInt32BE(0) % max); }; +// Generate random numbers between 0 and max without bias. +module.exports.random = function (max) { + const crypto = require('crypto'); + var maxmask = 1, r; + while (maxmask < max) { maxmask = (maxmask << 1) + 1; } + do { r = (crypto.randomBytes(4).readUInt32BE(0) & maxmask); } while (r > max); + return r; +}; // Split a comma seperated string, ignoring commas in quotes. module.exports.quoteSplit = function (str) { diff --git a/multiserver.js b/multiserver.js index 3bf2d2b7..ed210374 100644 --- a/multiserver.js +++ b/multiserver.js @@ -178,7 +178,8 @@ module.exports.CreateMultiServer = function (parent, args) { // Get the next retry time in milliseconds function getConnectRetryTime() { - if (obj.retryBackoff < 30000) { obj.retryBackoff += ((require('crypto').randomBytes(4).readUInt32BE(0) % 3000) + 1000); } + // The (random & 0x1FFF) creates a random number between 0 and 4096. + if (obj.retryBackoff < 30000) { obj.retryBackoff += ((require('crypto').randomBytes(4).readUInt32BE(0) & 0x1FFF) + 1000); } return obj.retryBackoff; }