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