Работая над серверным приложением, работающим на FreeBSD и использующим TCP, я заметил, что тесты TCP keepalive отправляются, даже несмотря на то, что мое приложение явно отключает SO_KEEPALIVE на сокетах TCP.
В соответствии сRFC1122 Раздел 4.2.3.6(TCP Keep-Alives):
«Если включены проверки активности, приложение ДОЛЖНО иметь возможность включать или выключать их для каждого TCP-соединения, и они ДОЛЖНЫ быть отключены по умолчанию».
Я обнаружил, что настраиваемый параметрnet.inet.tcp.always_keepaliveбыл включен (установлен на 1), и его отключение приведет к прекращению отправки пакетов проверки активности.
В чем причина включения этого поведения в FreeBSD? Насколько я могу судить, в Linux и Windows такой возможности нет, а в FreeBSD и Mac OS X она есть, поэтому они нарушают RFC.
Если говорить точнее, при каких обстоятельствах имеет смысл игнорировать пожелания заявителя?
В моем случае это простое решение, поскольку я могу отключить эту опцию, но мне хотелось бы понять, зачем она нужна.
Этот вопроспоказывает, что Linux ведет себя в соответствии с RFC.
решение1
Обоснование включения функции keep-alive по умолчанию приведено здесь:https://svnweb.freebsd.org/base?view=revision&revision=47752
Добавьте дескриптор для управления глобальными сообщениями TCP keepalive и включите их по умолчанию.
Несмотря на свое название, он не поддерживает TCP-сессии, а убивает их, если другой конец ушел в самоволку. Это часто случается с клиентами, которые используют NAT, динамическое назначение IP или имеют верхнюю границу времени безотказной работы в 2^32 * 10^-3 секунд.
Заметного увеличения сетевого трафика из-за этого не наблюдается: два минимальных TCP-пакета каждые два часа для активного TCP-соединения.
Многие серверы уже сами включают функцию keepalive.
Требования к хосту RFC существуют уже 10 лет, и в них не учтена потеря клиентов в современном Интернете.
В любом случае лучше отключить функцию keepalive, если этого требует приложение, например (на языке C):
int val = 0;
setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val));
но исправить это нелегко.
решение2
Я думаю, что настраиваемая ручка должна быть, но, возможно, было бы лучше оставить ее отключенной по умолчанию.
Я рассуждаю так: разработчик приложения может принять неправильные решения, и в конечном итоге контролировать такую сетевую политику должен системный администратор, а не разработчик приложения.