- NAME
- SYNOPSIS
- DESCRIPTION
  - CONSTRUCTOR
  - METHODS
- ANY ROUTINES
- NOTES
- CONFIG FORMAT
- BUGS
- SEE ALSO
- AUTHOR

# NAME

Net::SC - модуль для выстраивания цепочек socks серверов, и передачи через них данных.

# SYNOPSIS

     # CONNECT TO HOST
     # ----------------

     ...
     $self = new Net::SC(
                         Timeout         => ( $opt{'to'}  || 10      ),
                         Chain_Len       => ( $opt{'l'}   || 2       ),
                         Debug           => ( $opt{'d'}   || 0x04    ),
                         Log_File        => ( $opt{'lf'}  || undef   ),
                         Random_Chain    => ( $opt{'rnd'} || 0       ),
                         Auto_Save       => 1
                      );

     die unless ref $self;

     unless ( ( $rc = $self->connect( $host, $port ) ) == SOCKS_OKAY ) {
       print STDERR "Can't connect to $host:$port [".( socks_error($rc) )."]\n";
       exit;
     }

     $sh = $self->sh;

     print $sh, "Hello !!!\n";
     ...
     $self->close;
     ...

     #  BIND THE PORT
     # ---------------

     ...
     $self = new Net::SC(
                         Timeout         => ( $opt{'to'}  || 10      ),
                         Chain_len       => ( $opt{'l'}   || 2       ),
                         Debug           => ( $opt{'d'}   || 0x04    ),
                         Log_file        => ( $opt{'lf'}  || undef   ),
                         Random_chain    => ( $opt{'rnd'} || 0       ),
                         Auto_save       => 1
                      );

     die unless ref $self;

     unless ( ( $rc = $self->bind( $host, $port ) ) == SOCKS_OKAY ) {
       print STDERR "Can't bind port [".( socks_error($rc) )."]\n";
       exit;
     }

     print STDOUT "Binding the port : ",
                   $self->socks_param('listen_port'), "\n";
     print STDOUT "     in the host : ",
                   $self->socks_param('listen_addr'), "\n";
     print STDOUT "     for $host\n";

     $self->configure( TIMEOUT => 45 );
     unless ( ( $rc = $self->accept() ) == SOCKS_OKAY ) {
            return $rc;
     } else {
       $sh = $self->sh;
     }

     print STDOUT 'Connect from: ',
                            $self->socks_param('listen_addr'), ':',
                            $self->socks_param('listen_port'), "\n";

     print $sh 'Hello : ', $self->socks_param('listen_addr'), "\n";
     print $sh ' port : ', $self->socks_param('listen_port'), "\n";

     print STDOUT <$sh>;
     ...

    Более детально все показано в примерах.

# DESCRIPTION

## CONSTRUCTOR

new

  Инициализация внутренних переменных. В качестве параметров принимает хеш, со следующими ключами:

       TIMEOUT       - таймаут при создании цепочки, в секундах.

       CHAIN_LEN     - длина цепочки.

       DEBUG         - уровень отладки ( 0x00 | 0x01 | 0x02 | 0x04 )
                       0x00 - выключить
                       0x01 - включить
                       0x02 - выводить все ответы от sokcs серверов
                       0x04 - выводить все, что пишем socks'ам
                       0x08 - расширенная информация об ошибках

       CHAIN_FILE    - имя файла конфигурации.

       SYSLOG        - Если не undef то логи ведутся syslogd. Ключ
                       может принимать значения 'unix' или 'inet', т.е.
                       тип соединения с syslogd. По умолчанию undef.

       LOG_FILE      - имя лог файла, если undef то все пишем в STDERR
                       или передается syslogd.

       RANDOM_CHAIN  - правило построения цепочки ( 0 || 1 ).
                       0 - строить цепочку по порядку указанному в конфиге
                       1 - строить цепочку в произвольном порядке.

       CHECK_DELAY   - время в секундах, после которого при не удачной
                       попытке коннекта к серверу, его имя не будет
                       использовано при следующем создании цепочки.

       AUTO_SAVE     - автоматически записывать данные о socks серверах
                       в .db файл. Для более быстрого последующего коннекта.

       LOG_FH        - Файловый дескриптор для LOG файла. Используется только
                       если  LOG_FILE == undef

       LOOP_CONNECT - Прежде чем строить цепь дальше сервер коннектиться сам
                      себе.
                      0x01 - распространяется на socks v4
                      0x02 - распространяется на socks v5

       RESTORY_TYPE - При установке в 1 данные из кэша об отсутствующих
                      машинах в файле конфигурации удаляются.

## METHODS

connect

  Создает соединение с удаленной машиной.

       Использование:

        die unless $self->connect( $host, $port ) == SOCKS_OKAY;

bind

  Создает соединение с socks сервером для соединения с ним.

       Использование:

        die unless $self->bind( $host, $port ) == SOCKS_OKAY;

accept

  Ожидает соединение к соксу из вне...

       Использование:

        die unless $self->accept() == SOCKS_OKAY;
        $sh = $self->sh;

sh

  Возвращает сок хандле... Использование:

        $sh = $self->sh;

close

  Закрывает соединение через цепочку socks серверов...

       Использование:

        $self->close;

configure

  Изменить/прочитать текущие значения ( инициализируются при создании `new()` ).

       Использование:

        $self->configure( TIMEOUT => 10 );

        первый аргумент - секция ( TIMEOUT, DEBUG, CHAIN_LEN, etc )
        второй аргумент - новое значение. ( не обязательно )

socks_param

  Возвращает параметры последнего socks сервера в цепочке, такие как listen_port, listen_addr, etc...

       Использование:

        $listen_addr = $self->socks_param( 'listen_Addr' );

        $all_param = $self->socks_param();
        $listen_addr = $all_param->{'listen_addr'};

# ANY ROUTINES

        socks_error( ERROR_CODE )

        Возвращает сообщение об ошибке по его коду.

        Коды возврата socks'а :

        SOCKS_GENERAL_SOCKS_SERVER_FAILURE
        SOCKS_CONNECTION_NOT_ALLOWED_BY_RUL
        SOCKS_NETWORK_UNREACHABLE
        SOCKS_HOST_UNREACHABLE
        SOCKS_CONNECTION_REFUSED
        SOCKS_TTL_EXPIRED
        SOCKS_COMMAND_NOT_SUPPORTED
        SOCKS_ADDRESS_TYPE_NOT_SUPPORTED
        SOCKS_OKAY
        SOCKS_FAILED
        SOCKS_NO_IDENT
        SOCKS_USER_MISMATCH
        SOCKS_INCOMPLETE_AUTH
        SOCKS_BAD_AUTH
        SOCKS_SERVER_DENIES_AUTH_METHOD
        SOCKS_MISSING_SOCKS_SERVER_NET_DATA
        SOCKS_MISSING_PEER_NET_DATA
        SOCKS_SOCKS_SERVER_UNAVAILABLE
        SOCKS_TIMEOUT
        SOCKS_UNSUPPORTED_PROTOCOL_VERSION
        SOCKS_UNSUPPORTED_ADDRESS_TYPE
        SOCKS_HOSTNAME_LOOKUP_FAILURE

        $self->get_socks_count

         Возвращает число socks серверов которые могут быть
         использованы для построения цепочки. Без учета находящихся
         в данный момент в дауне.

        $self->mark_proxy ( $proxy_id, $status );

         Помечает прокси с порядковым номером в конфиге $id как временно
         недоступный - если $status != SOCKS_OKAY, иначе очищает счетчик
         неудачных попыток...

        $self->dump_cfg_data();

         Сбрасывает текущее состояние всех серверов в ${CHAIN_FILE}.db
         файл. Имеет смысл пользовать при большом списке соксов, многие
         из которых часто дохнут... При Auto_Save данные сбрасываются
         автоматически после каждого bind или connect.

        $self->restore_cfg_data();

         Восстанавливает значения таймаутов... Восстанавливаются
         значения только для тех серверов которые прописаны в текущем
         конфиге. Т.е. если конфиг пустой то ни чего не восстановится.
         При установленной переменной $Net::SC::RESTORE_TYPE в 1 данные
         из кеша удаляются, если в файле конфигурации не присутствует
         больше данный Socks сервер.

# NOTES

accept изменяет следующие значения возвращаемые socks_param:

     listen_addr - IP адрес удаленной машины
     listen_port - номер порта удаленной машины

Процедуры connect, bind, accept, при успешном завершении должны возвращать SOCKS_OKAY

# CONFIG FORMAT

     #host           :   port    : uid   :   pswd    : socks_proto
     192.168.1.90    :   1080    :       :           :   5
     ...

     Коментари  - строки начинающиеся на `#', строки из одних
     пробелов игнорируются.

# BUGS

При использовании на сервере ( socks v5 ) правил доступа для юзеров, т.е. Васе можно на яндекс, а Вере на гугль, и запросе Васи к гуглю такая ситуация не обрабатывается в create_chain, считается, что прокся жива, но выдается честный SOCKS_CONNECTION_NOT_ALLOWED_BY_RULESET, поэтому если надо ловите такие ситуации сами, и с помощью `mark_proxy()` помечайте сервер как недоступный...

В инете встречаются 'нехорошие' соксы которые вроде как есть, но не работают, поэтому например при коннекте к такому соксу v4 и длине цепочки равной 1, построение закончится неудачно даже если в конфиге еще остался список резервных серверов, для предотвращения этого можно попробовать пользоваться Loop_Connect - к каждому серверу в цепи коннектимся дважды, причем второй раз `через самого себя', что дает возможность проверить сервер...

Loop_Connect также полезен в том смысле, что если коннекты через сервер запрещены, то помечается как плохой следующий в цепи, ну и чтоб предотвратить это...

# SEE ALSO

perl, RFC 1928, RFC 1929, ...

# AUTHOR

     Okunev Igor V.  mailto:igor@prv.mts-nn.ru
                     http://www.mts-nn.ru/~gosha
                                     icq:106183300