23.11.1999, © Igor Sysoev, igor@nitek.ru

 

Как автоматически перезванивать провайдеру

 

Итак, мы получили PPP-соединение. Но в случае обрыва модемного соединения pppd завершает работу и интерфейс ppp0 вернётся в прежнее состояние. В принципе, можно написать скрипт, который бы в случае обрыва соединения запускал pppd снова:

#!/bin/sh

DEVICE=cuaa0

while [ ! -f /var/spool/lock/LCK..${DEVICE} ]; do
        pppd ${DEVICE} 57600 lock                       \
                connect '/etc/ppp/dial'                 \
                defaultroute noipdefault debug
        sleep 5
done

Этот скрипт каждые пять секунд проверяет наличие файла локирования (в нашем случае, это /var/spool/lock/LCK..cuaa0) и, в случае его отсутствия, запускает pppd снова.

Но, на самом деле, достаточно указать pppd параметр persist, что бы он делал это сам:

pppd cuaa0 57600 lock connect '/etc/ppp/dial'           \
        persist holdoff 5                               \
        defaultroute noipdefault debug

При разрыве соединения pppd возвращает интерфейс ppp0 в первоначальное неактивное состояние, то есть, интерфейс лишается адреса и удаляется все пути, в том числе и default route, проходящие через этот интерфейс. Но pppd не выходит, а пытается соединиться снова через пять секунд после разрыва соединения (параметр holdoff 5). pppd будет пытаться соединиться снова и снова до тех пор, пока его не прибьют

kill `cat /var/run/ppp0.pid`

Отметим, что для прибивания pppd в режиме persist недостаточно послать сигнал HUP (hang up), поскольку pppd будет пытаться звонить снова.

В версии pppd, которая идёт в составе FreeBSD 2.2.7, 2.2.8, 3.0-3.3, есть параметр connect-max-attempts N, который позволяет ограничить число попыток дозвониться.

Надо заметить, что у pppd есть параметр idle N, обычно используемый в режиме demand. Это параметр указывает pppd прервать соединение, если в течении N секунд по линии ничего не передавалось. Однако, в режиме persist этот параметр не имеет смысла, поскольку после разрыва соединения, вызваного бездействием линии, pppd будет пытаться соединиться снова. Но иногда такое поведение нежелательно - то есть, хотелось бы воспользоваться режимом persist, но при этом завершать работу pppd не с помощью команды kill, а чтобы он это делал сам после некоторого промежутка времени неактивности линии, заданного параметром idle. Добиться этого поможет патч.