LINUX.ORG.RU

Не видит обрыва связи


0

0

Есть подключение к интернет через GPRS. Всё работает замечательно, но есть одно неудобство.

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

То что связи давно нет программы замечают спустя чуть ли не час. Все это время, netstat показывает, что соединение ESTABLISHED.

Подскажите как сделать, чтобы программы сразу же чувствовали обрыв связи?

Догадываюсь, что нужно поправить какой-то параметр где-то в /proc/sys/net, но какой именно так и не сумел разобраться.

Ubuntu 7.10, набор номера делаю с помощью wvdial.

anonymous

в голову приходят /proc/sys/net/ipv4/tcp_keepalive_* Гугл что-то говорит на тему: http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/usingkeepalive.html

А wvdial можно в цикле запускать, чтобы связь сразу восстанавливалась (правда, уже, видимо, с другим айпишником и с потерей старых соединений).

С другой стороны, ты, наверное, хочешь, чтобы приложения сразу узнавали о том, что сетевой интерфейс пропал, как это бывает в оффтопике (там, чуть заденешь ногой ethernet-кабель, сразу все соединения рвутся).

alexsaa
()
Ответ на: комментарий от alexsaa

>в голову приходят /proc/sys/net/ipv4/tcp_keepalive_* Гугл что-то говорит на тему: >http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/usingkeepalive.html

Про tcp_keepalive_* я тоже нашел. Но видимо это что-то не то.

>А wvdial можно в цикле запускать, чтобы связь сразу восстанавливалась (правда, уже, видимо, с другим айпишником и с потерей старых соединений).

Вот в этом-то и проблема. Связь восстанавливается, но с потерей старых соединений.

>С другой стороны, ты, наверное, хочешь, чтобы приложения сразу узнавали о том, что сетевой интерфейс пропал, как это бывает в оффтопике (там, чуть заденешь ногой ethernet-кабель, сразу все соединения рвутся).

Наверное придется сделать таким образом.

Написать скриптик который бы периодически проверял бы вывод команды netstat -t -n, а именно столбец "Send-Q", в котором, если я правильно понимаю, показывается количество отосланных байт, на которое не пришло подтверждение о получении.

Изврат конечно, но ничего другого не придумывается...

anonymous
()
Ответ на: комментарий от anonymous

> Про tcp_keepalive_* я тоже нашел. Но видимо это что-то не то.

Но проблему-то оно решает? Казалось бы - оба параметра ставишь, скажем, в 300 секунд.

В принципе, связь не обязана рваться непосредственно на твоём сетевом интерфейсе. Поэтому в общем случае проблему потери соединения нельзя решить отслеживанием сетевого интерфейса, а только пакетами keepalive. Хотя, конечно, в твоём конкретном случае (на что, видимо, MS и ориентируется) лучше было бы мониторить по сетевому интерфейсу.

Так что не думаю, что tcp keep alive - это так уж "не то".

Send-Q естественным образом может быть ненулевым у любого (здорового и нездорового) соединения. И точно так же может быть нулевым. Какую информацию ты хочешь отсюда получить? О том, что отвалился wvdial? Об этом ты узнаешь и более прямыми методами - по завершению wvdial, по изменению таблицы роутинга, по выводу ifconfig или просто аккуратно пингуя что-то известное.

alexsaa
()
Ответ на: комментарий от alexsaa

>> Про tcp_keepalive_* я тоже нашел. Но видимо это что-то не то.

>Но проблему-то оно решает? Казалось бы - оба параметра ставишь, скажем, в 300 секунд.

К сожалению не решает. Либо я что-то неверно делаю... Делаю так:

sysctl -w net.ipv4.tcp_keepalive_time=60

sysctl -w net.ipv4.tcp_keepalive_probes=2

sysctl -w net.ipv4.tcp_keepalive_intvl=10

Параметры устанавливаются, однако это не меняет реакцию на разрыв связи. Как я понимаю, это должно означать, что по истечении 60 секунд неактивности предпринимаются 2 проверки соединения через 10 секунд. Но на самом деле и после указанного периода программа продолжает считать, что с соединением все впорядке.

>В принципе, связь не обязана рваться непосредственно на твоём сетевом интерфейсе. Поэтому в общем случае проблему потери соединения нельзя решить отслеживанием сетевого интерфейса, а только пакетами keepalive. Хотя, конечно, в твоём конкретном случае (на что, видимо, MS и ориентируется) лучше было бы мониторить по сетевому интерфейсу.

По сетевому интерфейсу не получится. wvdial сразу же восстанавливает подключение. Т. е. интерфейс ppp0 в отключенном состоянии находится всего несколько секунд. И, к тому же, да, совершенно точно подмечено -- обрыв связи действитель может быть и где-то дальше. Так что отслеживать состояние ppp0 это не выход.

>Так что не думаю, что tcp keep alive - это так уж "не то".

>Send-Q естественным образом может быть ненулевым у любого (здорового и нездорового) соединения. И точно так же может быть нулевым. Какую информацию ты хочешь отсюда получить? О том, что отвалился wvdial? Об этом ты узнаешь и более прямыми методами - по завершению wvdial, по изменению таблицы роутинга, по выводу ifconfig или просто аккуратно пингуя что-то известное.

Что получаю от Send-Q: Даю команду netstat -n -t | grep "tcp" | grep "5222"

Если в ответ вижу что-то типа

tcp 0 0 мойадрес:55214 jabber.ru:5222 ESTABLISHED

то со связью все впрорядке.

Если что-то типа

tcp 0 30 мойадрес:55214 jabber.ru:5222 ESTABLISHED

то это значит связь с сервером накрылась, сообщения не доходят, а jabber-клиент все еще "думает", что все впорядке. И едиственное, что помогает -- это выйти из программы и опять запустить ее. В венде же в такой ситуации jabber-клиент автоматически начинает реконнект и самостоятельно опять устанавливает связь с сервером. Этой же реакции хотелось бы добиться и в Linux.

Естественно связь с jabber-сервером только для примера. То же самое происходит если, например, сделать telnet www.ya.ru 80.

Send-Q -- единственный параметр, который я нешел, который начинает изменяться, когда начинаются проблемы со связью.

По завершению wvdial не подходит -- он не завершается, а восстанавливает связь. И это правильно -- удобно, что не нужно делать это вручную. Опять же связь может и где-то дальше рваться. Таблица маршрутизации не меняется. Вывод ifconfig не меняется. Пинг не подходит для проверки -- связь сразу же востанавливается.

anonymous
()
Ответ на: комментарий от anonymous

Там ещё пишут на тему того, что keepalive включается только по запросу приложения.

Насчёт приложений - psi имеет какую-то опцию "Посылать keep-alive пакеты (для поддержания в рабочем состоянии NAT-соединений)". Уж не знаю, то ли он посылает свои jabber'овские пакеты, то ли использует именно эту setsockopt() для включения стандартного механизма... Если первое, то ждать ему придётся тайм-аута соединения (вроде, минуты 2 или 10), а если второе - то столько, сколько задаётся этими параметрами keepalive.

С другой стороны, wvdial имеет опцию Auto Reconnect, её можно попробовать отключить, а запускать wvdial в цикле, в котором будет делаться ещё что-то полезное.

Send-Q > 0 ещё не гарантирует, что коннекта нет. Это случается всегда, когда пакет ушёл, а подтверждение ещё не вернулось.

Кстати, не включено ли у тебя случайно какого-нибудь файрволла, который режет icmp-сообщения от провайдера "destination port unreachable" для твоих исходящих пакетов по сдохшему соединению? Хотя я не уверен в роли этих сообщений в твоей ситуации.

alexsaa
()
Ответ на: комментарий от anonymous

> То же самое происходит если, например, сделать telnet www.ya.ru 80

Попробовал у себя: законнектился туда телнетом, после получения ответа вытащил шнурок эзернета, потом набил в консоли несколько символов, пару переводов строки - и тишина. Венда бы распознала отвал соединения при первой же попытке пересылки данных. Самое смешное что потом (у меня айпишник статически задан), когда шнурок воткнул обратно - оказалось что сессия жива, данные ушли на сервак, сервак прислал ответ.. Забавно блин :-|

anonymous
()

попробуй без всяких диалеров запускать pppd call ... c debug и nodetach и посмотри что напишет при обрыве.

WerNA ★★★★★
()
Ответ на: комментарий от alexsaa

>Насчёт приложений - psi имеет какую-то опцию "Посылать keep-alive пакеты (для поддержания в рабочем состоянии NAT-соединений)". Уж не знаю, то ли он посылает свои jabber'овские пакеты, то ли использует именно эту setsockopt() для включения стандартного механизма... Если первое, то ждать ему придётся тайм-аута соединения (вроде, минуты 2 или 10), а если второе - то столько, сколько задаётся этими параметрами keepalive.

Как раз пользуюсь PSI. С включенной этой опцией показание Send-Q увеличивается, с отключенной -- не увеличивается. Т. е. keep-alive пакеты посылаюся. Но PSI в любом случаи упорно считает, что связь не пропадала.

>Кстати, не включено ли у тебя случайно какого-нибудь файрволла, который режет icmp-сообщения от провайдера "destination port unreachable" для твоих исходящих пакетов по сдохшему соединению? Хотя я не уверен в роли этих сообщений в твоей ситуации.

Фаервол не задействован.

>попробуй без всяких диалеров запускать pppd call ... c debug и nodetach и посмотри что напишет при обрыве.

Диалер тут в общем-то ни причем. Вон другой anonymous вообще попробовал эзернет кабель выдернуть. С тем же эфектом.

Ладно, можно тему закрыть. Написал скрипт, который если Send-Q больше определенного значения подает звуковой сигнал и выводит сообщение, что проблемы со связью.

Спасибо всем кто ответил.

anonymous
()
Ответ на: комментарий от anonymous

>и посмотри что напишет при обрыве.

я имел в виду что _возможно_ при обрыве pppd что-то будет писать в консоль и ты увидишь что именно происходит.

WerNA ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.