Обычная последовательность обхода состояния во время активного закрытия TCP-соединения выглядит следующим образом:
ESTABLISHED
(appl: close, send FIN)
FIN_WAIT_1
(recv: ACK, send <nothing>)
FIN_WAIT_2
(recv: FIN, send ACK)
TIME_WAIT
(2MSL timeout)
CLOSED
Предположим, что приложение полностью закрывается и не хочет, чтобы соединение оставалось полуоткрытым.
Я понимаю, что реализация TCP в Linux применяет дополнительный тайм-аут, когда FIN_WAIT_2
, в соответствии с tcp (7) справочная страница:
tcp_fin_timeout (целое число; по умолчанию: 60; начиная с Linux 2.2)
Это указывает, сколько секунд ждать последнего пакета FIN, прежде чем сокет будет принудительно закрытый. Это строгое нарушение спецификации TCP, но необходимо для предотвращения атак типа «отказ в обслуживании». В Linux 2.2 значение по умолчанию было 180.
В ip-sysctl документация предлагает несколько иное объяснение:
tcp_fin_timeout - ЦЕЛОЕ
Время, в течение которого осиротевшее (больше не упоминаемое каким-либо приложением) соединение будет оставаться в состоянии FIN_WAIT_2 до того, как оно будет прервано на локальном конце. В то время как совершенно допустимое состояние «только прием» для несвязанного соединения, осиротевшее соединение в состоянии FIN_WAIT_2 могло бы в противном случае бесконечно ждать, пока удаленный компьютер не закроет свой конец соединения.
Ср. tcp_max_orphans
По умолчанию: 60 секунд
FIN_WAIT_2 ---(timeout)---> TIME_WAIT
?FIN_WAIT_2 ---(timeout)---> CLOSED
?FIN_WAIT_2
?FIN
RST
к входящим пакетам для соединения, которое считается закрытым? И когда он ничего не вернет?