<commit_before>-- This plugin is designed for testing received headers via rbl
-- Configuration:
-- .module 'received_rbl' {
--      rbl = "insecure-bl.rambler.ru";
--      rbl = "xbl.spamhaus.org";
--      symbol = "RECEIVED_RBL";
-- };

local symbol = 'RECEIVED_RBL'
local rbls = {}

function dns_cb(task, to_resolve, results, err)
	if results then
		local _,_,o4,o3,o2,o1,in_rbl = string.find(to_resolve, '(%d+)%.(%d+)%.(%d+)%.(%d+)%.(.+)')
		local ip = o1 .. '.' .. o2 .. '.' .. o3 .. '.' .. o4
		-- Find incoming rbl in rbls list
		for _,rbl in ipairs(rbls) do
			if rbl == in_rbl then
				task:insert_result(symbol, 1, rbl .. ': ' .. ip)
			else 
				local s, _ = string.find(rbl, in_rbl)
				if s then
					s, _ = string.find(rbl, ':')
					if s then
						task:insert_result(string.sub(rbl, s + 1, -1), 1, ip)
					else
						task:insert_result(symbol, 1, rbl .. ': ' .. ip)
					end
				end
			end
		end
	end
end

function received_cb (task)
	local recvh = task:get_received_headers()
    for _,rh in ipairs(recvh) do
        for k,v in pairs(rh) do
			if k == 'real_ip' then
				local _,_,o1,o2,o3,o4 = string.find(v, '(%d+)%.(%d+)%.(%d+)%.(%d+)')
				for _,rbl in ipairs(rbls) do
					local rbl_str = ''
					local rb_s,_ = string.find(rbl, ':')
					if rb_s then
						-- We have rbl in form some_rbl:SYMBOL, so get first part
						local actual_rbl = string.sub(rbl, 1, rb_s - 1)
						rbl_str = o4 .. '.' .. o3 .. '.' .. o2 .. '.' .. o1 .. '.' .. actual_rbl
					else
						rbl_str = o4 .. '.' .. o3 .. '.' .. o2 .. '.' .. o1 .. '.' .. rbl
					end
					task:resolve_dns_a(rbl_str, 'dns_cb')
				end
			end
        end
    end
end

-- Registration
if type(rspamd_config.get_api_version) ~= 'nil' then
	if rspamd_config:get_api_version() >= 1 then
		rspamd_config:register_module_option('received_rbl', 'symbol', 'string')
		rspamd_config:register_module_option('received_rbl', 'rbl', 'string')
	end
end

-- Configuration
local opts =  rspamd_config:get_all_opt('received_rbl')
if opts then
    if opts['symbol'] then
        symbol = opts['symbol']
        
        if opts['rbl'] then
			if type(opts['rbl']) == 'table' then
				rbls = opts['rbl']
			else
				rbls[1] = opts['rbl']
			end
        end
        for _,rbl in ipairs(rbls) do
        	local s, _ = string.find(rbl, ':')
			if s then
				if type(rspamd_config.get_api_version) ~= 'nil' then
					rspamd_config:register_virtual_symbol(string.sub(rbl, s + 1, -1), 1)
				end
			end
		end
        -- Register symbol's callback
        rspamd_config:register_symbol(symbol, 1.0, 'received_cb')
    end
    -- If no symbol defined, do not register this module
end<commit_msg>Optimize performance of received_rbl plugin.<commit_after>-- This plugin is designed for testing received headers via rbl
-- Configuration:
-- .module 'received_rbl' {
--      rbl = "insecure-bl.rambler.ru";
--      rbl = "xbl.spamhaus.org";
--      symbol = "RECEIVED_RBL";
-- };

local symbol = 'RECEIVED_RBL'
local rbls = {}

function dns_cb(task, to_resolve, results, err, sym)
	if results then
		local _,_,o4,o3,o2,o1,in_rbl = string.find(to_resolve, '^(%d+)%.(%d+)%.(%d+)%.(%d+)%.(.+)$')
		local ip = o1 .. '.' .. o2 .. '.' .. o3 .. '.' .. o4
		task:insert_result(sym, 1, in_rbl .. ': ' .. ip)
	end
end

function received_cb (task)
	local recvh = task:get_received_headers()
    for _,rh in ipairs(recvh) do
		if rh['real_ip'] then
			local _,_,o1,o2,o3,o4 = string.find(rh['real_ip'], '^(%d+)%.(%d+)%.(%d+)%.(%d+)$')
			for _,rbl in ipairs(rbls) do
				rbl_str = o4 .. '.' .. o3 .. '.' .. o2 .. '.' .. o1 .. '.' .. rbl['rbl']
				task:resolve_dns_a(rbl_str, 'dns_cb', rbl['symbol'])
			end
        end
    end
end

-- Registration
if type(rspamd_config.get_api_version) ~= 'nil' then
	if rspamd_config:get_api_version() >= 1 then
		rspamd_config:register_module_option('received_rbl', 'symbol', 'string')
		rspamd_config:register_module_option('received_rbl', 'rbl', 'string')
	end
end

-- Configuration
local opts =  rspamd_config:get_all_opt('received_rbl')
if opts then
    if opts['symbol'] then
        symbol = opts['symbol']
        local rbl_t = {}
        if opts['rbl'] then
			if type(opts['rbl']) == 'table' then
				rbl_t = opts['rbl']
			else
				rbl_t[1] = opts['rbl']
			end
        end
        for _,rbl in ipairs(rbl_t) do
        	local s, _ = string.find(rbl, ':')
			if s then
				local sym = string.sub(rbl, s + 1, -1)
				if type(rspamd_config.get_api_version) ~= 'nil' then
					rspamd_config:register_virtual_symbol(sym, 1)
				end
				table.insert(rbls, {symbol = sym, rbl = rbl})
			else
				table.insert(rbls, {symbol = symbol, rbl = rbl})
			end
		end
        -- Register symbol's callback
        rspamd_config:register_symbol(symbol, 1.0, 'received_cb')
    end
    -- If no symbol defined, do not register this module
end
{'fraction_non_alphanumeric': 0.16895547232625885, 'fraction_numerical': 0.012068248023304202, 'mean_word_length': 2.6638719512195124, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3201151', 'n_tokens_mistral': 2110, 'n_tokens_neox': 1871, 'n_words': 437}