Skip to content

Commit

Permalink
fix(patch): add global math.randomseed patch support (apache#5682)
Browse files Browse the repository at this point in the history
Co-authored-by: 罗泽轩 <spacewanderlzx@gmail.com>
  • Loading branch information
2 people authored and bzp2010 committed Dec 30, 2021
1 parent 3ab8645 commit 8cffb03
Showing 1 changed file with 47 additions and 0 deletions.
47 changes: 47 additions & 0 deletions apisix/patch.lua
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,23 @@ local ipmatcher = require("resty.ipmatcher")
local socket = require("socket")
local unix_socket = require("socket.unix")
local ssl = require("ssl")
local ngx = ngx
local get_phase = ngx.get_phase
local ngx_socket = ngx.socket
local original_tcp = ngx.socket.tcp
local original_udp = ngx.socket.udp
local concat_tab = table.concat
local debug = debug
local new_tab = require("table.new")
local log = ngx.log
local WARN = ngx.WARN
local ipairs = ipairs
local select = select
local setmetatable = setmetatable
local string = string
local table = table
local type = type
local tonumber = tonumber


local config_local
Expand Down Expand Up @@ -86,6 +91,48 @@ do
end


do -- `math.randomseed` patch
-- `math.random` generates PRND(pseudo-random numbers) from the seed set by `math.randomseed`
-- Many module libraries use `ngx.time` and `ngx.worker.pid` to generate seeds which may
-- loss randomness in container env (where pids are identical, e.g. root pid is 1)
-- Kubernetes may launch multi instance with deployment RS at the same time, `ngx.time` may
-- get same return in the pods.
-- Therefore, this global patch enforce entire framework to use
-- the best-practice PRND generates.

local resty_random = require("resty.random")
local math_randomseed = math.randomseed
local seeded = {}

-- make linter happy
-- luacheck: ignore
math.randomseed = function()
local worker_pid = ngx.worker.pid()

-- check seed mark
if seeded[worker_pid] then
log(ngx.DEBUG, debug.traceback("Random seed has been inited", 2))
return
end

-- generate randomseed
-- chose 6 from APISIX's SIX, 256 ^ 6 should do the trick
-- it shouldn't be large than 16 to prevent overflow.
local random_bytes = resty_random.bytes(6)
local t = {}

for i = 1, #random_bytes do
t[i] = string.byte(random_bytes, i)
end

local s = table.concat(t)

math_randomseed(tonumber(s))
seeded[worker_pid] = true
end
end -- do


local patch_udp_socket
do
local old_udp_sock_setpeername
Expand Down

0 comments on commit 8cffb03

Please sign in to comment.