Принудительная отмена состояния TIME-WAIT
К сожалению, иногда можно досрочно выйти из состояния TIM Е-WAIT. Это называется принудительной отменой (TIME-WAIT assassination) и бывает случай но или намеренно.
Сначала посмотрим, как это может произойти случайно. По стандарта RFC 793, если соединение находится в состоянии TIME-WAIT и приходит RST то соединение должно быть немедленно закрыто. Предположим, что имеет единение в состоянии TIME-WAIT и приходит старый сегмент-дубликат, который TCP не принимает (например, потому, что порядковый номер оказался вне окна приема). TCP посылает в ответ АСК, в котором указано, какой порядковый номер он ожидает (следующий за номером сегмента FIN, посланного другой стороной). Но у хоста на другой стороне уже нет информации о соединении, поэтому этот АСК он отвечает сегментом RST. Когда этот RST приходит хосту, у которого соединение находится в состоянии TIME-WAIT, тот немедленно закрывает соединение, - состояние TIME-WAIT принудительно отменено.
Эта ситуация описана в RFC 1337 [Braden 1992b], где также рассматриваются трудности, сопряженные с принудительной отменой состояния TIME-WAIT. Опасность состоит в возможности «воскрешения» старого соединения (то есть появления соединения с теми же двумя сокетами), что может привести к подтверждению старых данных, десинхронизации соединения с входом в бесконечный цикл и к ошибочному завершению нового соединения.
Это легко предотвратить, изменив протокол TCP так, чтобы в состоянии TIME-WAIT было разрешено игнорировать RST Хотя такое изменение, рекомендованное в RFC 1337, официально не одобрено, тем не менее в некоторых стеках оно реализовано.
Принудительно отменить состояние TIME-WAIT можно и намеренно. С помощью опции сокета SO_LINGER программист требует немедленного закрытия соединения даже в том случае, когда приложение выполняет «активное закрытие. Этот сомнительный прием иногда рекомендуют применять, чтобы вывести «упавший» сервер из состояния TIME-WAIT и запустить его заново. Подробнее об этой проблеме и более правильном способе ее решения будет рассказано в совете 23. Корректно написанное приложение никогда не должно манипулировать состоянием TIME-WAIT, поскольку это неотъемлемая часть механизма обеспечения надежности TCP.