Предохраняйся носками! Докучаев Дмитрий aka Forb Xakep, номер #066, стр. 066-118-2 Тонкости Perl Как я уже сказал, первое, что требуется от нашего прокси-сервера - открытие главного порта. На него будут приниматься запросы для новых подключений. В самом начале скрипта идет определение значения порта. По умолчанию это 5190 (пусть все думают, что у тебя на шелле находится ICQ-сервер :)). Тут же отображается пароль на доступ к серверу. Я задал очень простой пасс - 123 (при желании можешь его поменять). Код программы (без процедур) занимает всего несколько строк. В нем реализуется открытие порта и создание новых соединений. Создаем новые соединения unless (fork()) { use IO::Socket; use IO::Select; use POSIX ":sys_wait_h"; $|++; $bind=IO::Socket::INET->new(Listen=>10,Reuse=>1,LocalPort=>$startport) || die print "Can't bind MAIN socket on $startport: $!\n"; while(1) { while($client=$bind->accept()) { unless(fork()) { new_client($client); exit; }}}} Я специально не стал давать комментарии к коду. Тот, кто знает Perl, сам разберется, что к чему, а остальные поймут по ходу чтения статьи. Все начинается с вызова функции fork(). Ты знаешь, что форк создает идентичный подпроцесс. В данном случае мы описываем код, который выполняется в теле потомка (родитель завершает свое существование :)). По сути, я загнал процесс в бэкграунд. Ты сам в этом убедишься, когда запустишь скрипт - после старта вернется стандартное приглашение интерпретатора (будто ничего и не произошло). Далее заюзываем Socket для создания сокетов и Select - для управления ими. Чуть ниже идет загрузка части модуля POSIX, которая отвечает за корректное завершение убитых потомков. Напоследок отрубим буферизацию ($|++ практически то же, что $|=1). Теперь приступаем непосредственно к выполнению вышеописанного алгоритма. В переменной $bind будет храниться идентификатор сокета (или не будет - в случае если порт по каким-то причинам не открывается). Когда порт удачно засветился, впадаем в бесконечный цикл, в котором непрерывно анализируется состояние открытого сокета. Как только произошел коннект, сразу вызываем fork() и ответвляем процесс. Это делается для того, чтобы скрипт мог независимо обрабатывать сразу несколько подключений. Если процедура new_client() завершается, считаем соединение закрытым и выходим из подпроцесса. Обслуживаем клиента Тебе, несомненно, станет интересно, что же происходит в процедуре new_client(). Как я уже говорил, саба запускается в отдельном процессе, то есть не пересекается с остальными. И это правильно - клиенты не должны путаться друг у друга под ногами :). Итак, вот небольшая процедура, цель которой - аутентифицировать соединение и подготовиться к созданию необходимого туннеля. Создание туннеля sub new_client { my ($sid)=@_; $sid->recv($shake,1024); |