Этот скрипт читатель читает из pipe (созданный mkfifo) поток строк, получив сигнал SIGUSR1 от скрипта который пишет (писатель) в pipe, анализирует полученные строки и сохраняет результаты в файл и продолжает читать pipe. таких скриптов запущенно одновременно несколько, у каждого свой pipe. Скрипт писатель по кругу выбирает в какой pipe писать данные и раз в 15 сек меняет получателя посылая SIGUSR1 текущему читателю перед его сменой. По сути ничего супер выдающегося. Но есть проблема
строка line = assert(read_file:read())
завершается ошибкой И каждый раз непредсказуемо, то на первом круге все схлопывается то на 4 ом.
#!/usr/bin/lua
local P = require 'posix'
for k,v in pairs(P) do _G[k] = v end -- без этой строчки не вызываются функции модуля posix
local pipe_in = arg[1]
local switch_interval = tonumber(arg[3])
local instance = arg[4]
root_dir = "/opt/ddos_pps_to_ip"
results_dir = root_dir .. "/results"
pids_dir = root_dir .. "/pids"
local strings = {} -- массив строк для анализа
local ddos_dstip = {} -- массив с количеством пакетов на dstip
maxpps = 100 -- порог PPS превышение которого обнаруживает скрипт
pid=P.getpid"pid"
print("INSTANCE: " .. instance .. " " .. "PID: " .. pid)
fpid = io.open( pids_dir .. "/ddos" .. instance .. ".pid", "w")
io.output(fpid)
io.write(pid,"\n")
io.close(fpid)
read_file = io.open(pipe_in, "r") -- откроем pipe на чтение
fo = io.open(arg[2], "w") -- сохраним в файл считанные из pipe строки для отладки !!!!!!
io.output(fo)
function handler_sigusr1(signo) -- обработчик сигнала SIGUSR1
fo:flush () -- сбросим буфер в файл
print("PID:",pid,'handled',signo)
as=#strings
print("PID:",pid,"START CHECK DDOS",os.date"%T",time (),"Получено строк на обработку: ",as)
for i = 1, as, 1 do -- проанализируем все строки
dstip = string.sub (strings[i], 71, 85)
dstip = string.gsub (dstip," ","")
numpack = string.sub (strings[i], 100, 103)
numpack = string.gsub (numpack," ","")
numpack = tonumber(numpack)
num = ddos_dstip[dstip]
if numpack ~= nil then
if num ~= nil then -- первое появление IP адреса
num = tonumber(num)
ddos_dstip[dstip] = numpack + num
else
ddos_dstip[dstip] = numpack
end
end
end
rr = results_dir .. "/ddos" .. "_" .. time () .. "_" .. os.date"%T" .. ".result"
local result_file = io.open( rr , "w")
io.output(result_file)
for k, v in pairs(ddos_dstip) do
pps = math.floor(v/switch_interval)
if pps >= maxpps then
str = "dest_ip : " .. k .. " pps: " .. pps
io.write(str,"\n")
end
end
io.flush();
result_file:close()
ddos_dstip = {} -- очистим массив
strings = {} -- очистим массив
fo:flush ()
print("PID:",pid,"STOP CHECK DDOS ",os.date"%T",time ())
end
signal(SIGUSR1,handler_sigusr1)
while true do
line = assert(read_file:read()) -- assert вставлен для анализа
if line == nil then
print ("read PID:",pid,"Считал строку = nil")
break
end
table.insert(strings, line)
io.write(line,"\n") -- вывод в файл - дублирование строк для отладки
end
print ("PID:",pid,"ЗАВЕРШАЕМ РАБОТУ")
fo:close() -- это необходимо вынести в обработчик сигналов INT TERM
read_file:close() -- это необходимо вынести в обработчик сигналов INT TERM
и еще вопрос. число строк записанных в pipe процессом писателем никогда не совпадает с числом строк полученных процессом читателем, это нормально для IPC c использованием pipe?