Skip to content

Commit

Permalink
Fix: Optimize dovecot session handling and server selection.
Browse files Browse the repository at this point in the history
Refactored session cleaner to use a category map for clarity and reduced redundant checks. Adjusted Redis expiration times for both plugins to ensure session validity. Streamlined server selection process in the monitoring filter to enhance reliability and maintainability.

Signed-off-by: Christian Roessner <[email protected]>
  • Loading branch information
Christian Roessner committed Dec 9, 2024
1 parent ddcb534 commit e7afe2a
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 66 deletions.
112 changes: 57 additions & 55 deletions server/lua-plugins.d/filters/monitoring.lua
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ function nauthilus_call_filter(request)
end
else
if length == 1 then
local _, err_redis_expire = nauthilus_redis.redis_expire(custom_pool, redis_key, 3600)
local _, err_redis_expire = nauthilus_redis.redis_expire(custom_pool, redis_key, 900)
nauthilus_util.if_error_raise(err_redis_expire)
end
end
Expand Down Expand Up @@ -101,9 +101,9 @@ function nauthilus_call_filter(request)
if err_redis_hget then
if err_redis_hget ~= "redis: nil" then
nauthilus_builtin.custom_log_add(N .. "_redis_hget_error", err_redis_hget)
end

return nil
return nil
end
end

if server_from_session ~= "" then
Expand Down Expand Up @@ -141,82 +141,84 @@ function nauthilus_call_filter(request)
local server_host
local session = get_dovecot_session()

if session then
local result = {}
if session == nil then
session = request.protocol
end

local valid_servers = preprocess_backend_servers(nauthilus_backend.get_backend_servers())
local num_of_bs = nauthilus_util.table_length(valid_servers)
local result = {}

if request.debug then
result.caller = N .. ".lua"
result.level = "debug"
result.ts = nauthilus_util.get_current_timestamp()
result.session = request.session
result.dovecot_session = session
result.protocol = request.protocol
result.account = request.account
result.backend_servers_alive = tostring(num_of_bs)
local valid_servers = preprocess_backend_servers(nauthilus_backend.get_backend_servers())
local num_of_bs = nauthilus_util.table_length(valid_servers)

local backend_servers_hosts = {}
for _, server in ipairs(valid_servers) do
table.insert(backend_servers_hosts, server.host)
end
if request.debug then
result.caller = N .. ".lua"
result.level = "debug"
result.ts = nauthilus_util.get_current_timestamp()
result.session = request.session
result.dovecot_session = session
result.protocol = request.protocol
result.account = request.account
result.backend_servers_alive = tostring(num_of_bs)

result.backend_servers = table.concat(backend_servers_hosts, ", ")
local backend_servers_hosts = {}
for _, server in ipairs(valid_servers) do
table.insert(backend_servers_hosts, server.host)
end

if num_of_bs > 0 then
local maybe_server = get_server_from_sessions(session)
result.backend_servers = table.concat(backend_servers_hosts, ", ")
end

if maybe_server then
for _, server in ipairs(valid_servers) do
if server.host == maybe_server then
server_host = maybe_server
result.backend_server_selected = server_host
if num_of_bs > 0 then
local maybe_server = get_server_from_sessions(session)

break
end
if maybe_server then
for _, server in ipairs(valid_servers) do
if server.host == maybe_server then
server_host = maybe_server
result.backend_server_selected = server_host

break
end
end

if not server_host then
invalidate_stale_sessions()
if not server_host then
invalidate_stale_sessions()

server_host = valid_servers[math.random(1, num_of_bs)].host
result.backend_server_selected = server_host
end
else
server_host = valid_servers[math.random(1, num_of_bs)].host
result.backend_server_selected = server_host
end
else
server_host = valid_servers[math.random(1, num_of_bs)].host
result.backend_server_selected = server_host
end
end

if server_host then
local backend_result = nauthilus_backend_result.new()
local attributes = {}
if server_host then
local backend_result = nauthilus_backend_result.new()
local attributes = {}

add_session(session, server_host)
add_session(session, server_host)

local expected_server = get_server_from_sessions(session)
local expected_server = get_server_from_sessions(session)

-- Another client might have been faster at the same point in time...
if expected_server and server_host ~= expected_server then
server_host = expected_server
result.backend_server_selected = server_host
end
-- Another client might have been faster at the same point in time...
if expected_server and server_host ~= expected_server then
server_host = expected_server
result.backend_server_selected = server_host
end

attributes["Proxy-Host"] = server_host
attributes["Proxy-Host"] = server_host

nauthilus_builtin.custom_log_add(N .. "_backend_server", server_host)
nauthilus_builtin.custom_log_add(N .. "_backend_server", server_host)

backend_result:attributes(attributes)
nauthilus_backend.apply_backend_result(backend_result)
end
backend_result:attributes(attributes)
nauthilus_backend.apply_backend_result(backend_result)
end

nauthilus_util.print_result({ log_format = request.log_format }, result, nil)
nauthilus_util.print_result({ log_format = request.log_format }, result, nil)

if server_host == nil then
error("No backend servers are available")
end
if server_host == nil then
error("No backend servers are available")
end

return nauthilus_builtin.FILTER_ACCEPT, nauthilus_builtin.FILTER_RESULT_OK
Expand Down
28 changes: 17 additions & 11 deletions server/lua-plugins.d/hooks/dovecot-session-cleaner.lua
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ local json = require("json")

local N = "callback"

local CATEGORIES = {
["service:imap"] = true,
["service:pop3"] = true,
["service:lmtp"] = true,
["service:sieve"] = true,
}

function nauthilus_run_hook(logging, session)
local result = {}

Expand Down Expand Up @@ -61,15 +68,14 @@ function nauthilus_run_hook(logging, session)
end

result.state = "client disconnected"
result.dovecot_session = "unknown"

local is_cmd_noop = false

for k, v in pairs(body_table) do
if k == "categories" then
if nauthilus_util.is_table(v) then
for _, category in ipairs(v) do
if category == "service:imap" or category == "service:lmtp" then
if CATEGORIES[category] then
result.category = category
end
end
Expand Down Expand Up @@ -103,17 +109,17 @@ function nauthilus_run_hook(logging, session)
end
end

if result.category == "service:imap" or result.category == "service:pop3" or result.category == "service:lmtp" or result.category == "service:sieve" then
if result.dovecot_session ~= "unknown" then
local redis_key = "ntc:DS:" .. result.user
if CATEGORIES[result.category] then
local redis_key = "ntc:DS:" .. result.user

if is_cmd_noop then
result.cmd = "NOOP"
result.state = "client session refreshed"
if is_cmd_noop then
result.cmd = "NOOP"
result.state = "client session refreshed"

local _, err_redis_expire = nauthilus_redis.redis_expire(custom_pool, redis_key, 3600)
nauthilus_util.if_error_raise(err_redis_expire)
else
local _, err_redis_expire = nauthilus_redis.redis_expire(custom_pool, redis_key, 900)
nauthilus_util.if_error_raise(err_redis_expire)
else
if result.dovecot_session then
-- Cleanup dovecot session
local deleted, err_redis_hdel = nauthilus_redis.redis_hdel(custom_pool, redis_key, result.dovecot_session)
if err_redis_hdel then
Expand Down

0 comments on commit e7afe2a

Please sign in to comment.