Кратко
- Проба нулевого окна заставляет получателя повторить состояние, которое могло потеряться в ACK без данных.
- TCP сохраняет возможность продолжить передачу, а операционная система и приложение по-прежнему решают, когда прекратить ожидание и освободить ресурсы.
Соединение способно остановиться, даже когда обе стороны строго соблюдают правила. Принимающее приложение временно перестает читать данные, буфер заполняется, и TCP объявляет окно приема равным нулю. Отправитель подчиняется управлению потоком и прекращает обычную передачу. Позже приложение освобождает место, после чего получатель посылает ACK с увеличенным окном. Если именно этот пакет пропадет, у двух концов останутся разные представления об одном соединении.
Получатель знает, что кредит приема снова доступен, и считает, что уже сообщил об этом. Отправителю известна только последняя доставленная величина — ноль. ACK без данных сам по себе не получает гарантии надежной повторной передачи. Получателю может быть больше нечего отправлять, а отправитель не вправе послать те данные, которые естественным образом вызвали бы ответ. Соединение открыто, однако знание, необходимое для его использования, оказалось лишь на одной стороне.
Проба нулевого окна устраняет этот разрыв, не создавая вымышленной емкости. Даже при закрытом окне отправитель с определенными интервалами передает или повторяет небольшой объем, чтобы вызвать ответ получателя. В ACK тот указывает следующий ожидаемый номер последовательности и текущее окно. Если место уже появилось, отправитель наконец узнает об открытии. Если окно остается нулевым, он получает лишь свежую проверку состояния и продолжает соблюдать ограничение.
Основная конструкция присутствовала уже в RFC 793 1981 года. Отправляющий TCP должен был регулярно повторять передачу даже при нулевом окне. Получатель в таком состоянии, увидев сегмент, должен был отвечать ACK со следующим ожидаемым номером и текущим окном. Цель формулировалась узко: когда окно снова откроется, другой конец должен надежно получить это известие. Конкретная рекомендация по интервалу относилась к ранней редакции; долговечной оказалась возможность повторно вызвать сообщение о состоянии, которое иначе могло потеряться.
RFC 1122 в 1989 году превратил поддержку проб нулевого окна в однозначное требование для хоста. Документ прямо описал предотвращаемый сбой: TCP не передает ACK без данных надежно, поэтому потеря ACK, открывающего окно, способна навсегда подвесить соединение, если отправитель не делает проб. Первую пробу рекомендовалось отправлять после одного периода тайм-аута повторной передачи, а интервалы между последующими — увеличивать экспоненциально.
Такой ритм решает две разные задачи. Запрос после одного RTO не дает одиночной потере ACK надолго остановить поток. Постепенное увеличение интервала не позволяет законной длительной паузе породить постоянный поток запросов. Проба не дает отправителю права пренебречь получателем и не расширяет окно сама. Она снова спрашивает владельца окна о его нынешнем значении.
RFC 1122 проводит и другую важную границу. Принимающий TCP может держать предлагаемое окно закрытым неопределенно долго. Пока получатель отвечает на пробы подтверждениями, отправитель должен допускать сохранение соединения, хотя политика пользовательского тайм-аута приложения остается отдельной. Исторический пример — демон печати, который перестал принимать данные, потому что в принтере закончилась бумага. TCP не видит бумагу и не знает, когда ее добавят. Само по себе долгое нулевое окно не доказывает окончательную неисправность.
Положение отправителя в этой ситуации обычно называют persist condition, или состоянием persist. RFC 6429 вернулся к нему в 2011 году, потому что терпение протокола имеет цену, которую TCP не способен оценить самостоятельно. Удаленная сторона может постоянно объявлять ноль и при этом подтверждать каждую пробу. На отправителе тем временем остаются данные в очереди, буферы и состояние соединения. Если подобных соединений много, занятому серверу может не хватить ресурсов для законных клиентов.
RFC 6429 не объявил каждое нулевое окно атакой и не заменил пробы универсальным сроком принудительного закрытия. Он уточнил распределение ответственности. TCP не следует завершать соединение только из-за состояния persist, но операционная система или приложение вправе закрыть его и вернуть ресурсы согласно обычной политике. Возможность восстановить состояние протокола не означает обязанность владельца машины нести неограниченные расходы.
Действующая сводная спецификация TCP, RFC 9293, сохраняет это устройство. Пробы нулевого окна остаются обязательными. Получатель по-прежнему отвечает своим текущим окном и следующим ожидаемым номером последовательности. Отправителю следует начать после одного RTO и экспоненциально увеличивать следующие интервалы. Оговорка об управлении ресурсами также остается. Гарантируется не вечное ожидание при любых обстоятельствах, а возможность снова узнать состояние окна, пока система решила сохранять соединение.
Поэтому ACK на пробу — свидетельство транспортного уровня с ограниченным смыслом. Оно показывает, что удаленный TCP продолжает сообщать о пространстве последовательности и кредите приема. Оно не доказывает, что приложение продвигается, скоро начнет принимать данные или что соединение все еще оправдывает затраты. Проба восстанавливает потерянное обновление, но не обещает будущего прогресса.
Обзор для участников
Подробный контекст профиля
Войдите с подходящим уровнем подписки, чтобы открыть полный обзор и примечания к источникам.
Только для Стратегического сообщества
Стратегическое сообщество
Открыто всем читателям. Вступите и войдите, чтобы открыть обзоры профилей.
Вступить в Стратегическое сообществоТолько для Альянса лидеров
Альянс лидеров
Для проверенных владельцев IP-активов и руководителей. Войдите, чтобы открыть обзоры Альянса.
Вступить в Альянс лидеров
