|
Масштабное сканирование за две минуты! Дмитрий Докучаев aka Forb Xakep, номер #055, стр. 055-056-3 Начнем с главного - с порождения нового процесса. Эту процедуру принято выполнять в условии, чтобы разграничить действия родителя и потомка. Для нас важно запомнить PID (Process ID) в родителе и выполнить процедуру создания сокета в потомке. Эту операцию нужно совершить N раз (число N задается в начальных параметрах сканера). Затем идет перезаполнение массива ip-адресов (количество элементов которого равно N) и все повторяется заново. Таким образом, мы получаем ряд независимых процессов, протекающих почти одновременно, тем самым ускоряя работу сканера в N раз. XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Таблица 3: Аккуратное порождение подпроцессов XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX while(1) { ## Заводим бесконечный цикл @ips=@ipz[$once..$once+$pids]; ## Перезаполняем массив @ips, делая его равным определенному срезу массива ip-адресов (количество элементов = $pids) for ($i=0; $i<=$pids; $i++) { ## Создаем цикл for для каждого подпроцесса unless($ips[$i]) { ## Если элемента не существует, то сканирование должно быть завершено killpidz(); ## Переходим к убийству ВСЕХ порожденных ранее процессов exit print "Scan is complete\n"; ## И лишь затем корректно выходим из программы } if ($pid=fork()) { ## Создаем новый процесс push(@forked, $pid); ## В теле родителя заполняем массив идентификаторов } else { $res=connectIP($ips[$i]); ## В теле потомка создаем сокет logg($ips[$i],$res) if ($res ne 0); ## Логируем результат, если возврат отличен от нуля exit; ## Завершаем потомок! (очень важно) } } $once+=$pids; ## Увеличиваем начальное значение элементов на $pids раз killpidz(); ## Убиваем все потомки, чтобы не допустить переполнения } XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Этот важный фрагмент кода показывает гибкую работу Perl с процессами. Что мы имеем? Во-первых, массив @forked, который содержит идентификаторы порожденных процессов. Во-вторых, $pids независимых процессов, выполняющих свое черное дело - чтение баннера с сокета. На этот момент для нас важны две задачи: 1. Не допустить переполнения процессов, поддерживая _постоянное_ число рабочих потомков. 2. Дожидаться корректного завершения потомка, не убивая его раньше времени. ХХХ ЗАГОЛОВОК ХХХ Я тебя породил, я тебя и убью! Удовлетворить наши запросы поможет следующая, не менее важная процедура killpidz(), в которой происходит убийство всех процессов, хранящихся в массиве @forked. XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Таблица 4: Убийство процессов XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX |