Медленная работа сети является, пожалуй, самой распространенной проблемой, с которой приходится сталкиваться сетевым администраторам. Если при обрывах у нас просто нет связи и по крайней мере, диагностировать это достаточно просто, то «тормоза» в сети найти бывает гораздо сложнее. Но если кто‑нибудь пожалуется на медленную работу сети, то это еще не означает, что виной тому сама сеть. Прежде, чем начинать бороться с медленной сетью, необходимо выяснить, действительно ли она работает медленно.
И начнем мы с обсуждения функциональных средств, доступных в протоколе ТСР для устранения ошибок и управления потоками данных, передаваемых по сети. Существуют различные методики диагностики ошибок, но в рамках данной статьи мы будем использовать для диагностики средства протокола TCP.
Как работает протокол TCP
TCP является протоколом транспортного уровня, в котором реализован механизм надежной передачи данных. То есть, в отличие от UDP, где мы просто отправляем пакет и забываем про него, здесь мы сначала устанавливаем трехстороннее соединение, для того, чтобы потом начать передавать данные.
При установке соединения у нас происходит так называемое трехстороннее рукопожатие: клиент отправляет служебный пакет с флагом SYN, сервер в ответ отправляет пакет с флагами SYN, ACK и, наконец, клиент отправляет пакет ACK. И только после этого начинается передача полезной нагрузки.
В этом обмене у каждого пакета есть два числовых значения: Sequence и Acknowledgement. Принцип присвоения начальных значений Seq и Ack также представлен на рисунке ниже. Изначально x и y, участвующие в обмене это большие случайные числа.

Итак, с основами разобрались и теперь можем перейти к сути.
Повтор, еще повтор
При передаче каждого пакета по протоколу TCP нам важно получить подтверждение о том, что этот пакет был успешно получен. Для этого, после отправки каждого нового пакета (с новыми значениями Seq и Ack, посчитанными по представленному на рисунке выше алгоритму) отправитель ожидает получения пакета с флагом ACK, означающим что отправленный ранее пакет был успешно доставлен. В случае, если это не происходит отправитель повторно отправляет исходный пакет. Так работает механизм повторной передачи пакетов (retransmission).
Давайте рассмотрим этот механизм подробнее. В протоколе TCP главным средством, позволяющим определить необходимость повторной передачи пакета, является таймер, который отвечает за отсчет времени ожидания до повторной передачи (RTO, или Retransmission Timeout). Этот таймер запускается всякий раз, когда мы отправляем какой‑либо ТСР пакет и останавливается, когда получен пакет АСК. Промежуток времени между передачей и приемом пакета АСК называется временем на передачу и подтверждение приема (RTT, или Rouпd‑Trip Тime).
Когда пакет посылается, а получатель не отправляет в ответ подтверждающий пакет АСК, отправитель предполагает, что исходный пакет был потерян, и передает его еще раз. При повторной передаче пакета величина времени ожидания до повторной передачи (RTO) удваивается. И если подтверждающий пакет АСК не будет получен до истечения этого времени, то произойдет еще одна повторная передача пакета. А если и после этого подтверждающий пакет АСК не будет получен в ответ, то величина времени ожидания до повторной передачи удвоится снова. Этот процесс будет продолжаться до тех пор, пока отправитель не выполнит максимальное количество попыток повторной передачи, на которое он был настроен. Максимальное количество попыток зависит от величины, установленной в операционной системе передающего устройства.
Такое экспоненциальное увеличение интервалов при повторной передаче используется специально, для того, чтобы не загружать сеть повторными отправками пакетов.

По умолчанию хосты под управлением системы Windows совершают максимум 5 попыток повторной передачи, а большинство хостов под управлением Linux — до 15 таких попыток. Этот параметр настраивается в любой операционной системе.
Давайте посмотрим, как это выглядит на практике. В представленном ниже дампе трафика у нас имеется TCP пакет, отправленный на порт 1043. Подтверждающий ACK пакет отправитель не получил, в результате чего было выполнено несколько повторных отправлений данного пакета.

Как видно, Wireshark выделил цветом повторные отправки, что может существенно помочь при диагностике проблемы. Обычно подтверждающий пакет АСК должен посылаться в ответ по протоколу ТСР через довольно короткий промежуток времени после отправки первого пакета. Но в данном случае повторно передается следующий пакет. Об этом можно судить, глядя на пакет в панели Packet List, где в столбце Info ясно указана повторная передача [ТСР Retransmission], а текст из этого пакета выделен красным цветом на черном фоне.
Однако, выявить повторные отправки пакетов можно не только с помощью цветовой маркировки Wireshark. В окне Packet Details, под заголовком SEQ/ACK analysis мы видим сведения о том, что пакет (предположительно) отправлен повторно.

Эти полезные сведения предоставляются Wireshark на основе анализа полученных пакетов, и не входят в сам пакет. Они, в частности, сообщают, что пакет действительно передается повторно, а время ожидания до повторной передачи (RTO) составляет 0,206 и отсчитывается как прирост времени от момента передачи первого пакета.
Обратите также внимание, что данный пакет такой же, как и первоначальный пакет (вплоть до контрольной суммы). Можете убедиться в этом сами, сравнив повторно переданный пакет с первоначальным в панели Packet Bytes. Собственно, единственное отличие повторно отправленных пакетов — это время отправления каждого из них.
Более подробно статистику по времени отправления каждого из пакетов можно в разделе Statistics → Flow Graph.

Здесь мы видим экспоненциальный рост времени ожидания до повторной передачи по мере удвоения его величины после каждого отправления пакета.
Быстрый поиск
Наличие большого количества retransmission пакетов говорит о наличии проблем в работе сети. Даже если после нескольких повторов отправитель присылает ACK, все равно наличие задержек это не слишком хороший знак и неплохо бы разобраться, почему это происходит.
Для того, чтобы отфильтровать в дампе повторные отправленные пакеты можно воспользоваться фильтром tcp.analysis.retransmission.

В результате мы получим только повторные пакеты и дальше на основании этой информации уже можно будет делать выводы о том, с каким приложением или оборудованием возникли проблемы и что с этим можно дальше сделать.
Заключение
Способность хостов повторно передавать пакеты относится к самым основным функциональным средствам устранения ошибок в протоколе ТСР и позволяет предотвратить потери пакетов. Стоит отметить, что причин, по которым могут теряться (или не отправляться) ACK пакеты может быть довольно много. Так, у приложения на стороне получателя могут быть проблемы с производительностью, в результате чего оно может не отправлять ответы. Также проблемы могут быть у сетевого оборудования, в результате чего могут теряться пакеты для всего трафика, идущего через данное устройство. Кроме этого, важно отметить, что подобные проблемы могут носить временный характер и поэтому крайне важно, уметь выявлять наличие повторных отправлений пакетов в трафике.
В этой статье мы рассмотрели принципы работы packet retransmission в протоколе TCP и основные способы выявления данных пакетов в дампе трафика.
Если вам близки вопросы корпоративных сетей и маршрутизации, предлагаем вам углубиться в важные аспекты настройки и оптимизации сетевой инфраструктуры на открытых уроках Otus. Каждый из них затронет актуальные проблемы и подходы, с которыми сталкиваются профессионалы в сфере IT, и позволит вам расширить свои знания в области высокоскоростных сетей. Записывайтесь по ссылкам ниже: