Как стать автором
Обновить
524.23
OTUS
Цифровые навыки от ведущих экспертов

TCP: Что делать, когда окно равно нулю

Время на прочтение5 мин
Количество просмотров6.4K

Задержки (а по‑простому тормоза) в работе сети вряд ли кого‑то оставят равнодушным. Мы все очень не любим, когда медленно загружаются наши любимые веб‑ресурсы, или когда обрывается на 99% загрузка какого‑либо файла. Причин тормозов в сети может быть много — от проблем на физическом уровне и до медленной работы на уровне приложений. Сегодня мы поговорим об одной из причин задержек в сети, которую можно выявить с помощью анализатора пакета Wireshark. При этом не имеет особого значения, передается ли наш трафик в открытом виде или прячется за SSL: на верхние уровни мы забираться не будем. Важно только то, что это TCP трафик.

Окна в TCP

Протокол TCP содержит в своей архитектуре ряд функций, позволяющих препятствовать потере пакетов — например, такие механизмы, как повторные передачи и дублирующие подтверждения. Для предотвращения начала потери пакетов в TCP используется механизм скользящего окна (sliding‑window).

В механизме скользящего окна используется окно приема на стороне получателя пакетов для управления потоком данных. Принимающий хост указывает размер окна приема в байтах, сохраняет его в ТСР‑заголовке и сообщает передающему хосту, сколько данных он готов сохранить в памяти своего ТСР‑буфера. Именно в этой памяти данные временно хранятся до тех пор, пока они не будут переданы вверх по стеку протоколов на уровень приложений для последующей обработки. В итоге передающий хост может одновременно послать только то количество данных, которое указано в поле Window size (Размер окна) заголовка, полученного в ответ пакета ТСР. Чтобы передающий хост мог послать больше данных, принимающий хост должен отправить ему подтверждение о получении предыдущей порции данных. Он должен также очистить память своего ТСР‑буфера, обработав данные, занимающие эту память.

В целом, все достаточно просто. Принимающая сторона говорит, что готова принять, условно, три блока данных, отправитель передает их. Получает отправляет подтверждение, после чего отправляются следующие три блока данных и так далее.

В идеальном мире с постоянной пропускной способностью каналов размер окна действительно был бы постоянным значением. Однако, в реальности загрузка канала у нас постоянно меняется, и вместе с ней меняется и размер Window size. Процесс изменения размеров окна приема действует как в сторону уменьшения, так и увеличения. Так, если сервер способен обработать данные с большей скоростью, он может послать подтверждающий пакет АСК с большим размером окна приема.

Но ниже представлен пример приложения, у которого по каким‑то причинам уменьшился объем памяти, доступной в буфере, в результате чего получатель был вынужден уменьшить размер окна.

В случае, если получателю удалось решить свои проблемы с памятью, окно может быть снова увеличено. Но если быстро решить проблемы не удалось, и есть риск, что следующий блок данных обработать не удастся, получатель может указать размер Window=0. Что произойдет в таком случае?

Получив такой пакет, клиент прервет передачу данных и будет периодически отправлять пакет поддержания активным соединения. По сути, мы просто поддерживаем TCP соединение, при этом не передавая никаких данных. Когда получатель наконец‑то решит свои проблемы с памятью, он отправит пакет с обновлением размеров окна и передача полезной нагрузки продолжится.

От теории к практике

Теперь давайте вооружимся Wireshark и посмотрим, как выглядит соответствующий трафик.

В примере ниже у нас происходит информационный обмен между 192.168.0.20 и 192.168.0.30. В первых трех ACK пакетах значение Window уменьшается, видимо, у получателя проблемы с памятью и он не может обрабатывать больший объем данных.

Затем получатель отправляет пакет с нулевым окном. Однако после этого, по прошествии небольшого интервала времени, он отправляет обновление информации о размерах окна, в результате чего передача полезной нагрузки возобновляется.

В самом пакете информация о размере окна находится в TCP заголовке:

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

Здесь мы видим обмен трафиком между двумя узлами. В какой‑то момент один из участников отказывается принимать полезную нагрузку, отправив TCP ZeroWindow. После этого второй участник обмена с некоторой периодичностью отправляет Keep‑Alive пакеты, на которые первый участник продолжает отвечать нулевыми окнами. Пакеты Keep‑Alive также являются служебными и не несут в себе никакой полезной нагрузки.

Как искать

В приведенных примерах наши служебные пакеты были представлены в уже отфильтрованном виде без лишнего трафика. В реальных дампах у нас будет много других пакетов, и нам потребуется осуществить фильтрацию.

Для того чтобы отфильтровать в Wireshark пакеты с определенным размером окна, нужно воспользоваться фильтром tcp.window_size_value.

Например, для того, чтобы найти все пакеты с ненулевым размером окна, нужно указать tcp.window_size_value > 0

Для фильтрации пакетов с ZeroWindow можно, конечно, явно указать фильтр tcp.window_size_value == 0, а можно воспользоваться фильтром

tcp.analysis.zero_window

Для обнаружения Keep_Alive воспользуемся фильтром tcp.analysis.keep_alive

Также узнать, как с течением времени менялось значение TCP Window, можно с помощью графика. Для этого нужно выбрать Statistics → TCP Stream Graph → Window Scaling.

Заключение

Механизм скользящего окна, о котором мы сегодня говорили, непосредственно связан с неспособностью сервера принимать и обрабатывать данные. Любое уменьшение размера окна приема или даже его установка в нулевое состояние является непосредственным результатом какого‑то затруднения, возникшего на сервере. Поэтому, если вы видите большое количество таких пакетов в трафике, то это верный признак проблем с производительностью на принимающем узле и возможная причина задержек и сбоев в работе сетевых приложений.

В завершение рекомендую открытые уроки в Otus, подробнее о них ниже. Занятия пройдут в онлайн-формате и будут полезны сетевым инженерам, сетевым архитекторам и всем, кто глубоко интересуется современными сетевыми технологиями.

  • 5 февраля: ISIS vs. OSPF, или почему же ISIS до сих пор проигрывает битву OSPF в корпоративных сетях? Записаться

  • 18 февраля: Надежность и сети, или почему скорость сходимости STP уже очень давно никому не нравится? Записаться

Теги:
Хабы:
Всего голосов 14: ↑12 и ↓2+12
Комментарии3

Публикации

Информация

Сайт
otus.ru
Дата регистрации
Дата основания
Численность
101–200 человек
Местоположение
Россия
Представитель
OTUS