Sequence number tcp что это
Sequence number tcp что это
Глава 17 TCP: Transmission Control Protocol
В этой главе описаны сервисы, которые TCP предоставляет приложениям. Здесь же рассмотриваются поля TCP заголовка. В следующих главах мы подробно рассмотрим эти поля и расскажем, как TCP функционирует.
Описанию TCP посвящена эта глава, и следующие семь глав. В главе 18 будет рассказано, как устанавливаются и разрываются TCP соединения, в главе 19 и главе 20 мы рассмотрим обычную передачу данных, как в диалоговом использовании (удаленный заход), так и передачу файлов. В главе 21 мы подробно рассмотрим, как TCP осуществляет тайм-ауты и повторные передачи. И в главе 22 и главе 23 мы рассмотрим некоторые таймеры TCP. И в заключение, в главе 24 мы рассмотрим новые характеристики и производительность TCP.
Основная спецификация TCP находится в RFC 793 [ Postel 1981c], однако некоторые ошибки этого RFC исправлены в требованиях к хостам Host Requirements RFC.
Несмотря на то, что TCP и UDP используют один и тот же сетевой уровень (IP), TCP предоставляет приложениям абсолютно другие сервисы, нежели UDP. TCP предоставляет основанный на соединении надежный сервис потока байтов.
Всегда существуют две конечные точки, которые общаются друг с другом с помощью TCP соединения. Концепции, о которых мы говорили в главе 12, широковещательная рассылка и групповая рассылка, не имеют отношения к TCP.
Между двумя приложениями по TCP соединению осуществляется обмен потоком 8-битовых байтов. Автоматически TCP не вставляет записи маркеров. Это называется сервисом потока байтов (byte stream service). Если приложение на одном конце записало сначала 10 байт, затем 20 байт и затем еще 50 байт, приложение на другом конце соединения не может сказать какого размера была каждая запись. На другом конце эти 80 байт могут быть считаны, например, за 4 раза по 20 байт за каждый раз. Один конец соединения помещает поток байт в TCP, и точно так же идентичный поток байт появляется на другом конце.
TCP не интерпретирует содержимое байтов. TCP понятия не имеет о том, происходит ли обмен двоичными данными, ASCII символами, EBCDIC символами или чем-либо еще. Эта интерпретация потока байтов осуществляется приложениями на каждой стороне соединения.
Вспомним, что данные TCP инкапсулируются в IP датаграммы, как показано на рисунке 17.1.
Рисунок 17.1 Инкапсуляция TCP данных в IP датаграмму.
На рисунке 17.2 показан формат TCP заголовка. Обычно его размер составляет 20 байт, если не присутствуют опции.
Рисунок 17.2 TCP заголовок.
Каждый TCP сегмент содержит номер порта (port number) источника и назначения, с помощью которых идентифицируются отправляющее и принимающее приложения. Эти два значения вместе с IP адресом источника и назначения в IP заголовке уникально идентифицируют каждое соединение.
Так как каждый байт, который участвует в обмене, пронумерован, номер подтверждения (acknowledgment number) это следующий номер последовательности, который ожидает получить отправитель подтверждения. Это номер последовательности плюс 1 последнего успешно принятого байта данных. Это поле принимается в рассмотрение, только если флаг ACK (описан ниже) взведен.
Отправка ACK не стоит ничего (это означает, что на подтверждение не тратится сегмент), потому что 32-битное поле номера подтверждения всегда является частью заголовка, так же как и флаг ACK. Мы увидим, что когда соединение установлено, это поле всегда установлено и флаг ACK всегда взведен.
TCP предоставляет для прикладного уровня полнодуплексный сервис. Это означает, что данные могут передаваться в каждом направлении независимо от другого направления. Однако, на каждом конце соединения необходимо отслеживать номер последовательности данных, передаваемых в каждом направлении.
Длина заголовка (header length) содержит длину заголовка в 32-битных словах. Это объясняется тем, что длина поля опций переменная. С 4-битным полем у TCP есть ограничение на длину заголовка в 60 байт. Без опций, однако, стандартный размер составляет 20 байт.
В TCP заголовке существуют 6 флаговых битов. Один или несколько из них могут быть установлены в единицу в одно и то же время. Здесь мы кратко опишем их использование, а позже опишем каждый флаг более подробно в соответствующих главах.
Указатель срочности (urgent pointer) будет рассмотрен в разделе «Режим срочности (Urgent Mode)» главы 20.
Номер подтверждения необходимо принять в рассмотрение (acknowledgment).
Получатель должен передать эти данные приложению как можно скорее (глава 20, раздел «Флаг PUSH»).
Синхронизирующий номер последовательности для установления соединения. Этот следующий флаги описаны в главе 18.
Отправитель заканчивает посылку данных.
Контрольная сумма (checksum) охватывает собой весь TCP сегмент: TCP заголовок и TCP данные. Это обязательное поле, которое должно быть рассчитано и сохранено отправителем, а затем проверено получателем. Контрольная сумма TCP рассчитывается так же как контрольная сумма UDP, с использованием псевдозаголовка, как описано в разделе «Контрольная сумма UDP» главы 11.
Указатель срочности (urgent pointer) действителен только в том случае, если установлен флаг URG. Этот указатель является положительным смещением, которое должно быть прибавлено к полю номера последовательности сегмента, чтобы получить номер последовательности последнего байта срочных данных. Режим срочности TCP это способ, с помощью которого отправитель передает срочные данные на удаленный конец. Мы рассмотрим эту характеристику в разделе «Режим срочности (Urgent Mode)» главы 20.
На рисунке 17.2 мы видели, что раздел данных в TCP сегменте необязателен. В главе 18 мы увидим, что когда устанавливается соединение или когда соединение разрывается, сегменты содержат только TCP заголовки с возможными опциями. Заголовок без данных также используется, чтобы подтвердить принятые данные, если в этом направлении не надо передавать данные. Также существует несколько случаев тайм-аутов, когда сегмент может быть отправлен без данных.
TCP предоставляет надежный, ориентированный на соединения, и ориентированный на поток байтов сервис транспортного уровня. Мы коротко рассмотрели все поля TCP заголовка, подробное описание полей приведено в следующих главах.
TCP строит пакеты из пользовательских данных, упаковывая их в сегменты, устанавливает тайм-ауты в тот момент, когда он посылает данные, подтверждает принятые данные с удаленного конца, меняет порядок данных, которые пришли хаотически, отбрасывает продублированные данные, осуществляет контроль потока данных, рассчитывает и проверяет контрольную сумму в конечных точках передачи.
TCP используется множеством популярных приложений, таких Telnet, Rlogin, FTP и электронная почта (SMTP).
Протокол TCP: что нужно знать специалисту по анализу сетевого трафика!
По нашему опыту, когда дело доходит до низкоуровневого анализа TCP девять из десяти ИТ специалистов в компаниях среднего и крупного бизнеса чувствуют себя неуверенно. Не могут точно сказать, что такое ретрансмиссии, размер окна и т.д. Большинство материалов в интернете по этой теме больше походят на научные работы. В этой статье мы попытаемся донести с практической точки зрения, что же полезного прячет в себе протокол TCP для того, кто занимается анализом сетевого трафика.
В каких случаях нам нужен анализ TCP пакетов?
Как показывает практика, современные системы анализа сетевого трафика имеют большую базу протоколов и готовых шаблонов для программного обеспечения. Это позволяет без труда разбивать транзакции на логические части. К сожалению, далеко не для всех задач бизнеса удаётся найти готовые продукты и в каждой компании обязательно найдётся парочка «самописных» или кастомизированных приложений. Как же анализировать трафик от таких приложений?
База анализатора трафика не имеет информации, в каком бите содержится код реквеста, какой код соответствует респонсу и т.д. В таких ситуациях приходится прибегать к самым азам сетевой науки – TCP анализу. Давайте рассмотрим, что прячет внутри себя этот протокол.
По своей сути TCP является протоколом транспортного уровня. Он позволяет осуществить соединение одного сокета (IP-адрес + порт) хоста источника с сокетом хоста назначения. Заголовок IP будет содержать информацию, связанную с IP-адресами, а заголовок TCP — информацию о порте.
Заголовок TCP
Заголовки TCP перемещаются по сети для установления, поддержки и завершения TCP-соединений, а также передачи данных.
Рисунок 1. Заголовок TCP
В заголовке TCP содержаться следующие поля:
Механизм передачи сообщений TCP
Перед тем, как данные могут быть переданы между двумя узлами, в TCP, в отличие от UDP, предусмотрена стадия установки соединения. Также, после того, как все данные были переданы, наступает стадия завершения соединения. Таким образом, осуществление каждого TCP-соединения можно условно разделить на три фазы:
Установка соединения осуществляется с помощью, так называемого трехстороннего рукопожатия TCP. Инициатором соединения может выступать любая сторона. Однако чтобы упростить рассмотрения данного вопроса в рамках данной статьи, мы рассмотрим пример, когда клиент инициализирует соединение с сервером.
Рисунок 2. Трехстороннее рукопожатие TCP
(Пакет №1). Клиент отправляет пакет с установленным флагом SYN и случайным числом («R1»), включенным в поле порядкового номера (sequence number).
(Пакет №2). При получении пакета №1 сервер в ответ отправляет пакет с установленным флагом SYN, а также с установленным флагом ACK. Поле порядкового номера будет содержать новое случайное число («R2»), а поле номера подтверждения будет содержать значение порядкового номера клиента, увеличенного на единицу (то есть «R1 + 1»). Таким образом, он будет соответствовать следующему порядковому номеру, который сервер ожидает получить от клиента.
(Пакет №3). В ответ на пакет SYN от сервера (пакет №2) клиент отправляет пакет с установленным флагом ACK и полем номера подтверждения с числом «R2 + 1». По аналогии, это число будет соответствовать следующему порядковому номеру, который клиент ожидает получить от сервера.
После инициализации соединения полезная нагрузка будет перемещаться в обоих направлениях TCP-соединения. Все пакеты в обязательном порядке будут содержать установленный флаг ACK. Другие флаги, такие как, например, PSH или URG, могут быть, а могут и не быть установленными.
При нормальном завершении TCP-соединения в большинстве случаев инициализируется процедура, называемая двухсторонним рукопожатием, в ходе которой каждая сторона закрывает свой конец виртуального канала и освобождает все задействованные ресурсы. Обычно эта фаза начинается с того, что один из задействованных процессов приложения сигнализирует своему уровню TCP, что сеанс связи больше не нужен. Со стороны этого устройства отправляется сообщение с установленным флагом FIN (отметим, что этот пакет не обязательно должен быть пустым, он также может содержать полезную нагрузку), чтобы сообщить другому устройству о своем желании завершить открытое соединение. Затем получение этого сообщения подтверждается (сообщение от отвечающего устройства с установленным флагом ACK, говорящем о получении сообщения FIN). Когда отвечающее устройство готово, оно также отправляет сообщение с установленным флагом FIN, и, после получения в ответ подтверждающего получение сообщения с установленным флагом ACK или ожидания определенного периода времени, предусмотренного для получения ACK, сеанс полностью закрывается. Состояния, через которые проходят два соединенных устройства во время обычного завершения соединения, отличаются, потому что устройство, инициирующее завершение сеанса, ведет себя несколько иначе, чем устройство, которое получает запрос на завершение. В частности, TCP на устройстве, получающем начальный запрос на завершение, должен сразу информировать об этом процесс своего приложения и дождаться от него сигнала о том, что приложение готово к этой процедуре. Инициирующему устройству не нужно это делать, поскольку именно приложение и выступило инициатором. Более подробно завершении TCP-соединения смотрите здесь (http://www.tcpipguide.com/free/t_TCPConnectionTermination-2.htm).
Рисунок 3. Завершение TCP-соединения
На уровне TCP нет сообщений типа «keep-alive», и поэтому, даже если сеанс соединения в какой-то момент времени становится неактивным, он все равно будет продолжаться до тех пор, пока не будет отправлен следующий пакет.
Когда мы отправляем HTTP-запрос по сети, нам сразу нужно создать TCP-соединение. Однако в HTTP 1.0 возможность повторного использования соединения по умолчанию закрыта (если заголовок «keep-alive = close» дополнительно не включен в заголовок HTTP), то есть TCP-соединение автоматически закрывается после получения запроса и отправки ответа. Так как процесс создания TCP-соединения относительно затратный (он требует дополнительных затрат процессорных ресурсов и памяти, а также увеличивает сетевой обмен между сервером и клиентом, что особенно становится актуальным при создании защищенных соединений), то все это увеличивает количество лагов и повышает вероятность перегрузки сети. Поэтому для HTTP 1.1 было решено оставлять TCP-соединение открытым до тех пор, пока одна из сторон не решит прекратить его.
С другой стороны, если соединения не будут закрываться после того, как клиенты получат все необходимые им данные, задействованные ресурсы сервера для поддержания этих соединений не будут доступны другим клиентам. Поэтому HTTP-серверы, чтобы обеспечить больший контроль над потоком данных, используют временные интервалы (таймауты) для поддержки функциональности «keep-alive» для неактивных соединений (длящихся по умолчанию, в зависимости от архитектуры и конфигурации сервера, не более нескольких десятков секунд, а то и просто нескольких секунд), а также максимальное число отправляемых запросов «keep-alive», прежде чем сеанс без активного соединения будет остановлен. Более подробно о функциональности «keep-alive» вы можете узнать здесь (https://blog.stackpath.com/glossary/keep-alive/).
Подписывайтесь на рассылку, делитесь статьями в соцсетях и задавайте вопросы в комментариях!
How to prepare TCP
Когда кому-то или чему-то становится плохо, то требуется нечто большее, чем просто констатация данного факта.
Первое — это диагностика проблемы, определение причин сбоя.
Взять и измерить давление, сделать пальпацию, проверить уровень масла в двигателе и так далее, и тому подобное.
А что если проблемы возникли при передаче данных в интернет/интранет-сети?
Тут, по-видимому, потребуются особые средства диагностики.
В особенности будут полезны средства, которые позволяют проводить статистический анализ большого количества данных.
Существует множество разных инструментов.
Часть из них можно найти в такой замечательной программе, как Wireshark.
В меню Statistics (Статистика) Wireshark представлен богатый набор функциональности.
При этом результаты могут представляться не только в общем, но и графическом виде.
Как раз о графическом виде и хочется поговорить.
Рассказать о наборе из пяти графиков статистики TCP StreamGraph.
Позволяют легко и эффективно проводить анализ и диагностику TCP-соединений.
Но прежде чем начинать говорить о графиках, для их лучшего понимания рассмотрим основы теории TCP.
Минимум, необходимый для общего понимания TCP StreamGraph
Ниже приведена картинка с частным случаем TCP обмена данных.
Следует рассматривать как упрощенный вариант.
В примере, нумерация сегментов начинается с единицы.
Хотя в действительности это не совсем так.
Однако то же самое показывает и Wireshark при дефолтных настройках.
Отправитель шлет два сегмента (Seq=1 и Seq=6), содержащих по пять байт данных каждый.
Получатель отвечает, что все байты до 10 получены успешно и ожидается следующий 11-й сегмент (Ack=11).
Отправитель передает еще два (Seq=11 и Seq=16), один из которых теряется в сети (Seq=11).
Получатель констатирует, что в потоке принятых данных возник разрыв.
Сообщает, что начиная с первого байта непрерывно приняты только 10 байт и он по-прежнему ждет 11-й сегмент (Ack=11).
Однако одновременно с этим в подтверждающем сегменте указывает SACK (Selective acknowledgment, выборочное подтверждение) блок, с диапазоном байт, полученных после разрыва. Благодаря SACK отправитель повторно передаст только пропавший сегмент (Seq=11). Без SACK потребовалось бы повторять Seq=16 тоже. Использование SACK должно поддерживаться обеими сторонами обмена.
А теперь рассмотрим процесс передачи данных в TCP-соединении через TCP StreamGraph в Wireshark.
Однако, чтобы не описывать графики просто так, сделаю это на простом и понятном примере.
Загружу файл с тестового сервера на свой компьютер, используя протокол HTTP.
Для этого воспользуюсь утилитой curl, а не веб-браузером.
curl поможет создать некоторые проблемы, которые увидим на графиках.
Проблемы возникнут вследствие того, что загрузка будет вестись напрямую в консоль, а не в файл.
Итак, запускаю Wireshark, включаю захват трафика.
Загружаю утилитой curl тестовый файл размером 10Мб с сервера v4.speedtest.reliableservers.com (10MBtest.bin).
Останавливаю захват трафика.
В полученном сетевом дампе Wireshark ищу HTTP пакет с GET запросом файла 10MBtest.bin и определяю номер TCP–соединения, в котором он загружался. Или ищем по фильтру tcp contains «10MBtest.bin».
Фильтрую весь трафик по номеру TCP-соединения в котором загружался тестовый файл tcp.stream==5.
А вот теперь смотрим TCP StreamGraph.
Важно знать, что все графики из TCP StreamGraph строятся по одному TCP соединению и являются направленными.
Направление указывает, в какую сторону двигался анализируемый поток данных от клиента к серверу или наоборот.
Time-Sequence Graph (Stevens)
Time-Sequence Graph (Stevens) выглядит как наклонная кривая, состоящая из точек.
Координаты каждой точки графика — это значение Sequence number TCP сегмента (ось Y — Байты) и время его захвата (ось X — секунды).
Соответственно, как говорилось ранее, учитываются только сегменты с данными одного TCP-соединения, перемещавшиеся в определенном направлении, от серверу к клиенту (загрузка, download) или наоборот (выгрузка, upload).
Согласно теории Sequence number, это номер первого байта данных сегмента в общем потоке данных.
Поэтому можно сказать, что график показывает динамику загрузки/выгрузки байт данных в TCP соединении по времени.
На любом участке легко рассчитывается скорость передачи данных, (Sequence number деленная на Time, получаем Байт/сек).
Как следствие, по изменениям наклона участков кривой можно судить об изменениях скорости передачи данных.
В идеальных условиях график выглядит как диагональная линия с большим углом наклона.
Однако на практике это не всегда так.
По аномалиям на кривой графика можно выявить задержки в передаче данных, потери сегментов и их повторные отправки (Retransmission).
На приведенном ниже примере графика во время загрузки файла возникли две схожие проблемы с остановкой передачи данных и потерей сегментов.
Горячие клавиши в Windows (краткая справка):
Пошаговое увеличение или уменьшение масштаба графика выполняется через клавиши i/o или прямым выделением участка мышью. Возврат к исходному масштабу, клавиша Home.
Пробел — превращает курсор в перекрестие с вертикальной и горизонтальной вспомогательными линиями.
Цифровые клавиши с 1 по 5 — выбор другого графика из набора.
Ctrl + правая кнопка мыши — появляется окно с увеличенным изображением участка графика из под курсора.
Щелчок мышки на любой точке графика приводит к переходу в интерфейсе Wireshark на соответствующий ей TCP пакет.
Time-Sequence Graph (tcptrace)
По внешнему виду Time-Sequence Graph (tcptrace) напоминает предыдущий график и предназначен для более полного анализа возможных проблем. В нем все так же выводятся значения Sequence number сегментов потока данных на временной шкале.
Однако добавился еще один атрибут сегмента — его размер (TCP Segment Len).
Поэтому сегменты отображаются уже не точками, а вертикальными отрезками с засечками на концах, как английская буква I — «ай». Основание отрезка это Sequence number, а длина — размер сегмента в байтах.
Также на графике выводится информация из обратного потока подтверждающих сегментов, Window (Win), Acknowledgment number (Ack) и SACK. Значения Ack отображаются ступенчатой кривой, проходящей ниже сегментов данных.
Каждая ступень, ее вершина — это момент времени прихода подтверждения об общем количестве непрерывно принятых байт получателем.
Аналогично “ступенчато” отображается размер окна принимающей стороны Win.
Кривая проходит выше потока данных.
Вершина ступени — это сумма значений Ack и Win подтверждающего сегмента.
Синими вертикальными линиями визуализируются SACK блоки.
SACK может присутствовать в подтверждении, если в сплошном потоке полученных данных возникли разрывы.
Синяя линия — это диапазон байт полученных после разрыва.
В общем виде график представляет собой “коридор” из двух ступенчатых кривых, внутри которого перемещаются сегменты с данными. Сужение «коридора» говорит об уменьшении размера окна приема (Win), расширение — об обратном.
На предыдущем графике были обнаружены две проблемы с остановкой передачи данных.
Time-Sequence Graph (tcptrace) внес ясность в причины случившегося.
Уменьшился размер окна (Win) на принимающей стороне.
Отправитель передал максимально допустимое количество сегментов с данными, чтобы не переполнить окно, и остановился.
После того, как получатель сообщил об увеличении размера окна (Window Update), передача данных возобновилась.
Throughput Graph
Throughput Graph выглядит как множество точек, иногда расположенных весьма хаотично.
Координаты каждой точки — это расчетная скорость перемещения сегмента в потоке данных (ось Y — Байт/сек) и время его захвата (ось X — секунды).
Если быть точным, для сглаживания колебаний на графике фиксируются не реальные, а усредненные значения скорости.
Используется усредняющая функция скользящего среднего (Moving Average, MA) на 20 значений за предыдущий период.
По коду Wireshark, средняя скорость N-го сегмента равна сумме длин всех сегментов от N до N-20, деленная на дельту по времени между их захватом.
Как следствие, две задержки в передаче данных, вызванные уменьшением размера окна (Win), привели к падению Throughput в проблемные моменты времени. В остальное время скорость закачки варьировалась в пределах диапазона от 1.4 до 3.4 МБайт.
Round Trip Time Graph
Round Trip Time (RTT) — это время, прошедшее между отправкой сегмента с данными и получением подтверждения о его успешной доставке.
Round Trip Time Graph показывает RTT (ось Y — секунды) по каждому сегмента из потока данных.
Идентификатором сегмента выступает его Sequence number (ось X — Байты).
При нормальных условиях большая часть точек концентрируется в нижней части графика.
В примере RTT почти все время не превышает 0.1 сек., за исключением проблемных моментов, когда RTT подскакивала до 0.4 сек.
Все графики связаны между собой формулой Throughput = Window size / RTT
Window Scaling Graph
Координаты каждой точки Window Scaling Graph — это размер окна Windowsize (ось Y — Байты) сегмента на момент времени его захвата (ось X — секунды).
В Window Scaling Graph присутствует информация о двех проблемных случаях сокращения размера окна до критичных размеров.
Это полностью подтверждает показаниями на Time-Sequence Graph.
Заключение
Ну вот, кажется, и все. Что хотел — сказал.
Информации по теме гораздо больше. В статье были изложены только основы, помогающие лучше понять графики из TCP StreamGraph, Wireshark.
Эти графики очень полезны в своем практическом применении и позволяют делать всесторонний обзор любого TCP-соединения, выявлять сетевые проблемы.
Конечно, есть и другие инструменты, подобные TCP StreamGraph, например, tcptrace, captcp.
Не стоит забывать и о IO Graph того же Wireshark. Он обладает более обширной функциональностью выходящей далеко за пределы TCP StreamGraph.
Надеюсь, статья окажется полезна всем тем, кто интересуется сетевыми технологиями или изучает протокол TCP.