LINUX.ORG.RU

странное поведение keepalive


0

1

приветствую!

устанавливаю для сокета свои настройки keepalive. в локалке - все работает как надо - 20 сек, но в интернете - 15 мин.

есть идеи, почему такое может происходить?

благодарен.

★★★

Идей нет, потому что нифига не понятно. Как устанавливает, что устанавливаете, как проверяете/измеряете время?

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

просто подумал, что это врядли зависит от того как устанавливаю...

код:

int opt = 1;
setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof(opt));
opt = 2;
setsockopt(sock, SOL_TCP, TCP_KEEPCNT, &opt, sizeof(opt));
setsockopt(sock, SOL_TCP, TCP_KEEPINTVL, &opt, sizeof(opt));
opt = 10;
setsockopt(sock, SOL_TCP, TCP_KEEPIDLE, &opt, sizeof(opt));

niXman ★★★
() автор топика
Последнее исправление: niXman (всего исправлений: 1)
Ответ на: комментарий от niXman

А 20 секунд/15 минут это что — время разрыва соединения или интервал между NOP-пакетами? На уровне tcp/icmp пакетов сравинвали соединение по локальной сети и через интернет?

И, по хорошему, нужно бы проверять код возврата от setsockopt().

mky ★★★★★
()

В «интернете» - это как проверялось то? Сидит по пути прокся или файрволл хитрый - и привет tcp keepalive

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

А 20 секунд/15 минут это что — время разрыва соединения или интервал между NOP-пакетами?

время разрыва.

проверяли так: запускаются две программки на двух разных машинах в одной сети. работают себе, общаются... тут, внезапно выдергиваем LAN, и ждем. через 20 сек сервер понимает что клиент отвалился, и завершает сессию.

На уровне tcp/icmp пакетов сравнивали соединение по локальной сети и через интернет?

не подскажете, как это сделать?

нужно бы проверять код возврата от setsockopt().

в реальном коде он проверяется. это я отсюда убрал проверку, дабы не захламлять.

niXman ★★★
() автор топика
Последнее исправление: niXman (всего исправлений: 1)
Ответ на: комментарий от niXman

> На уровне tcp/icmp пакетов сравнивали соединение по локальной сети и через интернет?

не подскажете, как это сделать?

Я думал, в делаете где-то DROP, а не кабель выдёргиваете. А так, запускаете tcpdump на перехват icmp и tcp пакетов и смотрите что уходит, что приходит. Может в случае с локалкой обрыв связи обнаруживается из-за отсутствия arp-ответов.

Вобще, в исхдном стандарте keepalive говорилось про только 2 часа и про то, что он должен помогать обнаруживать зависшие tcp-сессии. Использование его для такого, практически мнгновенного обнаружения разрыва, как-бы идеологически не верно.

Нагуглил тут, что если в момент обрыва связи приложение делает read() сокета, то keepalive пакеты ходят и обрыв связи обнаруживается бысто, а если write(), то в канал отправляются только пакеты с данными (без keepalive-пактов), пакеты с данными отправляются по известному алгоритму с удвоеним таймаута повторной передачи, пока все эти таймауты не выйдут, ошибки не будет, независимо от настроек keepalive. Возможно, это ваш случай, так как при работе через интернет время прохождения пакетов больше и выдёргивая шнурок легче поймать приложение в момент write().

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

изначально, проверка на «жив ли клиент» производилась пересылкой пакета по TCP, по таймеру. но я хотел попробовать без таймеров, чтоб переложить эту заботу на ОС и таким образом снизить оверхед и расход памяти, создаваемые этими таймерами.

но, похоже не судьба...

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