mirror of
https://github.com/ntop/ntopng.git
synced 2026-04-30 07:59:35 +00:00
224 lines
7.2 KiB
Lua
224 lines
7.2 KiB
Lua
--
|
|
-- (C) 2013-20 - ntop.org
|
|
--
|
|
|
|
local plugins_consts_utils = {}
|
|
local dirs = ntop.getDirs()
|
|
|
|
-- ##############################################
|
|
|
|
local AVAILABLE_CONSTS = {
|
|
flow = {
|
|
min_id = 1, max_id = 63, reuse_ids = true,
|
|
reserved_ids = {
|
|
status_normal = 0,
|
|
},
|
|
},
|
|
alert = {
|
|
min_id = 0, max_id = 255, reuse_ids = false,
|
|
}
|
|
}
|
|
|
|
-- ##############################################
|
|
|
|
local id_requests = {
|
|
flow = {},
|
|
alert = {}
|
|
}
|
|
|
|
-- ##############################################
|
|
|
|
local function assigned_ids_hname(const_type)
|
|
return string.format("ntopng.prefs.plugins_consts_utils.assigned_ids.const_type_%s", const_type)
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
local function assigned_id_key(const_type, const_key)
|
|
local hname = assigned_ids_hname(const_type)
|
|
return string.format("%s.const_key_%s", hname, const_key)
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
local function get_assigned_ids(const_type)
|
|
local hname = assigned_ids_hname(const_type)
|
|
local assigned_ids = ntop.getHashAllCache(hname) or {}
|
|
local cur_id_to_key = {}
|
|
local cur_key_to_id = {}
|
|
|
|
for const_id, const_key in pairs(assigned_ids) do
|
|
local const_id_n = tonumber(const_id)
|
|
|
|
if const_id_n < AVAILABLE_CONSTS[const_type]["min_id"] or const_id_n > AVAILABLE_CONSTS[const_type]["max_id"] then
|
|
traceError(TRACE_ERROR, TRACE_CONSOLE, string.format("Ignoring id %i outside boundaries for '%s'", const_id_n, const_type))
|
|
else
|
|
cur_id_to_key[const_id_n] = const_key
|
|
cur_key_to_id[const_key] = const_id_n
|
|
end
|
|
end
|
|
|
|
return cur_id_to_key, cur_key_to_id
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
local function commit_new_ids(const_type, new_ids)
|
|
local hname = assigned_ids_hname(const_type)
|
|
|
|
for const_key, const_id in pairs(new_ids) do
|
|
local const_id_s = string.format("%i", const_id)
|
|
|
|
-- Attempt to lookup for the id in the cache. Attempting to commit a new id to an existing
|
|
-- it, causes the old key to be reused the new key. This is used for example when reusing ids
|
|
local existing = ntop.getHashCache(hname, const_id)
|
|
if not isEmptyString(existing) then
|
|
traceError(TRACE_NORMAL, TRACE_CONSOLE, string.format("Reusing id %i '%s' to '%s'", const_id, existing, const_key))
|
|
ntop.delHashCache(hname, const_id_s)
|
|
|
|
local existing_kname = assigned_id_key(const_type, existing)
|
|
ntop.delCache(existing_kname)
|
|
end
|
|
|
|
-- Now it's time to set the new id, both in the hash table...
|
|
ntop.setHashCache(hname, const_id, const_key)
|
|
|
|
-- ... and as a single key
|
|
local kname = assigned_id_key(const_type, const_key)
|
|
ntop.setPref(kname, const_id_s)
|
|
end
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
function plugins_consts_utils.clear_id_requests(const_type)
|
|
id_requests[const_type] = {}
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
function plugins_consts_utils.request_id(const_type, const_key)
|
|
if not AVAILABLE_CONSTS[const_type] then
|
|
traceError(TRACE_ERROR, TRACE_CONSOLE, string.format("Unknown const type '%s'", const_type))
|
|
return
|
|
end
|
|
|
|
id_requests[const_type][#id_requests[const_type] + 1] = const_key
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
function plugins_consts_utils.assign_requested_ids(const_type)
|
|
if not AVAILABLE_CONSTS[const_type] then
|
|
traceError(TRACE_ERROR, TRACE_CONSOLE, string.format("Unknown const type '%s'", const_type))
|
|
return
|
|
end
|
|
|
|
local cur_id_to_key, cur_key_to_id = get_assigned_ids(const_type)
|
|
local available_ids = {}
|
|
local used_ids = {}
|
|
local new_ids = {}
|
|
local found_ids = {}
|
|
local deferred_requests = {}
|
|
local reused_ids = {}
|
|
|
|
-- Prepare used and available ids by iterating the current existing ids (i.e., those
|
|
-- that have already been assigned)
|
|
for i = AVAILABLE_CONSTS[const_type]["min_id"], AVAILABLE_CONSTS[const_type]["max_id"] do
|
|
if cur_id_to_key[i] then
|
|
used_ids[#used_ids + 1] = i
|
|
else
|
|
available_ids[#available_ids + 1] = i
|
|
end
|
|
end
|
|
|
|
for _, req in ipairs(id_requests[const_type]) do
|
|
if AVAILABLE_CONSTS[const_type]["reserved_ids"] and AVAILABLE_CONSTS[const_type]["reserved_ids"][req] then
|
|
-- Id among those reserved, so id is already assigned and there is nothing to do
|
|
elseif cur_key_to_id[req] then
|
|
-- Id found: already assigned, nothing to do
|
|
found_ids[#found_ids + 1] = cur_key_to_id[req]
|
|
elseif #available_ids > 0 then
|
|
-- At least an id is available in the pool of available ids
|
|
new_ids[req] = table.remove(available_ids, 1)
|
|
elseif AVAILABLE_CONSTS[const_type]["reuse_ids"] then
|
|
-- No ids available but reuse of old ids is enabled
|
|
deferred_requests[#deferred_requests + 1] = req
|
|
else
|
|
-- No ids available and reuse not allowed, unable to assign.
|
|
traceError(TRACE_ERROR, TRACE_CONSOLE, string.format("Unable to assign an id to '%s' for const type '%s'. No more ids available", req, const_type))
|
|
end
|
|
end
|
|
|
|
commit_new_ids(const_type, new_ids)
|
|
|
|
if #deferred_requests > 0 then
|
|
for _, used_id in ipairs(used_ids) do
|
|
local used_id_found = false
|
|
|
|
for _, found_id in ipairs(found_ids) do
|
|
if used_id == found_id then
|
|
-- Used id found during this run, cannot reuse it
|
|
used_id_found = true
|
|
break
|
|
end
|
|
end
|
|
|
|
if not used_id_found then
|
|
-- This id is used but not found so it means no plugin is using it (during this run) and it can be reused
|
|
reused_ids[table.remove(deferred_requests, 1)] = used_id
|
|
end
|
|
|
|
if #deferred_requests == 0 then
|
|
-- No more work to do
|
|
break
|
|
end
|
|
end
|
|
|
|
commit_new_ids(const_type, reused_ids)
|
|
|
|
if #deferred_requests > 0 then
|
|
for _, req in ipairs(deferred_requests) do
|
|
traceError(TRACE_ERROR, TRACE_CONSOLE, string.format("Unable to reuse any id for '%s' with const type '%s'.", req, const_type))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
function plugins_consts_utils.get_assigned_id(const_type, const_key)
|
|
if not AVAILABLE_CONSTS[const_type] then
|
|
traceError(TRACE_ERROR, TRACE_CONSOLE, string.format("Unknown const type '%s'", const_type))
|
|
return
|
|
end
|
|
|
|
if AVAILABLE_CONSTS[const_type]["reserved_ids"] and AVAILABLE_CONSTS[const_type]["reserved_ids"][const_key] then
|
|
return AVAILABLE_CONSTS[const_type]["reserved_ids"][const_key]
|
|
end
|
|
|
|
-- Avoid reading the whole hash, just read the single key to re-use also ntopng internal caching mechanism
|
|
local kname = assigned_id_key(const_type, const_key)
|
|
local assigned_id = tonumber(ntop.getPref(kname))
|
|
|
|
if assigned_id == nil then
|
|
-- Not found in the internal cache, check the hash
|
|
local cur_id_to_key, cur_key_to_id = get_assigned_ids(const_type)
|
|
if cur_key_to_id[const_key] ~= nil then
|
|
return cur_key_to_id[const_key]
|
|
end
|
|
end
|
|
|
|
-- Make sure the index is within the configured bounds
|
|
if assigned_id then
|
|
if assigned_id < AVAILABLE_CONSTS[const_type]["min_id"] or assigned_id > AVAILABLE_CONSTS[const_type]["max_id"] then
|
|
traceError(TRACE_ERROR, TRACE_CONSOLE, string.format("Ignoring id %i outside boundaries for '%s'", assigned_id, const_type))
|
|
-- Clear it as it should have that value
|
|
assigned_id = nil
|
|
end
|
|
end
|
|
|
|
return assigned_id
|
|
end
|
|
|
|
return plugins_consts_utils
|