(Почему) FreeBSD 'net.inet.tcp.always_keepalive' нарушает RFC1122?

(Почему) FreeBSD 'net.inet.tcp.always_keepalive' нарушает RFC1122?

Работая над серверным приложением, работающим на 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

Я думаю, что настраиваемая ручка должна быть, но, возможно, было бы лучше оставить ее отключенной по умолчанию.

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

Связанный контент