Как можно охарактеризовать порт источника
Нужны новые клиенты? Тогда Вам рекомендуем посмотреть этот раздел нашего сайта
_____
Заголовок UDP всегда имеет длину 64 бита. Поля, определённые в сегменте UDP (см. рисунок) включают следующие:
1. Порт отправителя (Source port): номер порта источника(16 бит)
2. Порт получателя (Destination port): номер порта назначения (16 бит)
3. Длина сообщения (Length): длина заголовка UDP и данных UDP (16 бит)
4. Контрольная сумма (Checksum): вычисленная контрольная сумма полей заголовка и данных (16 бит)
5. Данные (Data): данные протокола вышележащего уровня (upper-layer protocol – ULP) (переменная длина)
Примеры протоколов, которые используют UDP: TFTP, SNMP, Network File System (NFS) и Domain Name System (DNS).
Заголовок TCP содержит информацию, которая определена TCP протоколом. В данном разделе описаны компоненты заголовка TCP.

Сегменты TCP передаются с помощью использования пакетов IP. Заголовок TCP следует за заголовком IP,. Это разделение допускает существование других протоколов на уровне хоста, отличных от TCP. Поля TCP заголовка включают следующие:
Порт отправителя (Source port): номер порта источника (16 бит)
Порт получателя (Destination port): номер порта назначения (16 бит)
Порядковый номер (Sequence number): порядковый номер первого октета данных
сегмента, используемый для гарантии правильного упорядочения приходящих данных
(32 бита)
Номер подтверждения (Acknowledgment number): следующий ожидаемый октет
TCP (32 бита)
Длина заголовка (Header length): количество 32-битных слов в заголовке (4 бита)
Зарезервировано (Reserved): установлено в 0 (3 бита)
Управляющие биты (Control bits): функции управления – такие как установка,
перегрузка и разрыв сеанса (9 бит). Одиночный бит, который имеет специальное
значение, часто рассматриваемое как флаг.
Окно (Window): число октетов, которое устройство согласно принять (16 бит)
Контрольная сумма (Checksum): вычисленная контрольная сумма полей заголовка и
данных (16 бит)
Указатель срочности данных (Urgent): показывает конец срочных данных (16 бит)
Опции (Options): в настоящее время определена одна опция – максимальный размер
сегмента TCP (0 или 32 бита)
Данные (Data): данные протокола вышележащего уровня (upper-layer protocol – ULP)
(переменная длина)
HackWare.ru
Этичный хакинг и тестирование на проникновение, информационная безопасность
Транспортные протоколы TCP и UDP
Оглавление: Компьютерные сети
6. Канальный уровень передачи данных
7. Маршрутизация данных
8. Служебный протокол ICMP
10. Настройка сетевых подключений в командной строке Linux
11. Определение проблем работы сети
12. Туннелизация
Сходства и различия TCP и UDP
В первой части «Как работают компьютерные сети» мы узнали, что для передачи информации используются транспортные протоколы TCP и UDP. В физическом смысле эти протоколы представляют собой сетевые пакеты. Каждый сетевой пакет передаёт небольшой фрагмент информации, поэтому данные разбиваются на много пакетов.
Каждый сетевой пакет обоих протоколов TCP и UDP состоит из двух частей:
- заголовок
- непосредственно данные
В заголовке содержится «служебная информация» (можно сказать, что это метаданные) — порты пункта назначения и исходного узла, номер пакета в потоке, тип пакета и так далее.
Различие между протоколами TCP и UDP в том, что протокол TCP имеет механизм контроля полноты переданных данных — если какой-либо пакет был потерян или повреждён, то предусмотрен механизм для проверки этого факта и повторной отправки пакета. В протоколе UDP такого механизма нет — то есть если потерян пакет протокола UDP, то узел, который его отправил, никогда об этом не узнает, а принимающая сторона никогда не узнает, что ей был отправлен потерянный пакет UDP.
Может возникнуть вопрос, зачем вообще нужен такой ненадёжный протокол UDP, если есть надёжный протокол TCP? Платой за надёжность протокола TCP является то, что в бухгалтерии называется «накладные расходы» (overheads) — суть в том, что для обеспечения механизма контроля доставки пакетов в протоколе TCP отправляется много данных, которые не содержат полезной информации, а служат только для установки и контроля соединения. К примеру, чтобы отправить хотя бы одни пакет с полезными данными в TCP нужно завершить трёхступенчатое рукопожатие, которое заключается в отправке 1 особого пакета от источника к пункту назначения, получения 1 пакета о возможности установить соединения и отправки ещё 1 специального пакета от источника с подтверждением, что всё готово к отправке — за это время с помощью протокола UDP можно было бы отправить уже несколько пакетов с полезными данными.
По этой причине, оба протокола TCP и UDP являются «хорошими» — важно правильно их использовать. Например, при потоковом вещании видео неважно, какой пакет был потерян секунду или две назад. Но при открытии веб-страницы, когда из-за неполных данных могут возникнуть проблемы с обработкой запроса от HTTP протокола, напротив, нужно следить за доставкой и целостностью каждого пакета с данными.
Детальное понимание TCP и UDP имеет значение при:
- анализе сетевого трафика
- настройке сетевого файервола iptables
- понимания и защиты от DoS атак некоторого вида.
К примеру, понимая механизм TCP подключения, можно настроить файлервол (iptables) так, что будут запрещены все новые подключения с сохранением существующих, либо запретить любые входящие подключения с полным разрешением исходящих, понимать и предотвращать ряд DoS атак, понимать SYN и другие виды сканирований — почему они возможны и каков их механизм и т.д..
Протокол TCP
Transmission Control Protocol (TCP, протокол управления передачей) — один из основных протоколов передачи данных интернета, предназначен для управления передачей данных.
Из-за перегрузки сети, балансировки нагрузки трафика или непредсказуемого поведения сети, IP-пакеты могут быть потеряны, дублированы или доставлены не в неправильном порядке. TCP обнаруживает эти проблемы, запрашивает повторную передачу потерянных данных, переупорядочивает неупорядоченные данные и даже помогает минимизировать перегрузку сети, чтобы уменьшить возникновение других проблем. Если данные все ещё остаются недоставленными, источник уведомляется об этом сбое. После того, как получатель TCP собрал последовательность первоначально переданных октетов, он передаёт их принимающему приложению. Таким образом, TCP абстрагирует связь приложения от базовых сетевых деталей.
TCP широко используется во многих интернет-приложениях, включая World Wide Web (WWW), электронную почту, протокол передачи файлов, Secure Shell, одноранговый обмен файлами и потоковое мультимедиа.
Протокол TCP оптимизирован для точной доставки, а не для своевременной доставки, и может вызывать относительно длительные задержки (порядка секунд) при ожидании сообщений, вышедших из строя или повторных передач потерянных сообщений. Поэтому он не особенно подходит для приложений реального времени, таких как передача голоса по IP.
Итак, механизм TCP предоставляет поток данных с предварительной установкой соединения, осуществляет повторный запрос данных в случае потери данных и устраняет дублирование при получении двух копий одного пакета, гарантируя тем самым, в отличие от UDP, целостность передаваемых данных и уведомление отправителя о результатах передачи.
Алгоритм работы TCP следующий:
- Устанавливается трёхэтапное рукопожатие между двумя узлами. На этом этапе узлы согласуют два числа — начальные номера первого пакета для каждого из узлов.
- При отправке пакетов узлы последовательно номеруют их, то есть каждому сетевому пакету присвоен один из последовательных номеров.
- В дополнении к номеру, для каждого пакета рассчитывается контрольная сумма. Получив пакет, вновь рассчитывается контрольная сумма для полученных данных — если она не совпадает, значит пакет был повреждён при передаче.
- Итак, поскольку все пакеты имеют последовательные номера, то становится видно если какие-то из них отсутствуют. В этом случае отправляется запрос на повторную отправку пакета.
- Если для какого-то пакета не совпала контрольная сумма, то отправляется запрос на повторную отправку пакета.
В общем, используя два простых механизма — контрольную сумму и последовательную нумерацию каждого пакета — удаётся достичь надёжности передачи данных и возможности организовать их в правильную последовательность независимо от того, в каком порядке они доставлены.
Всё это возможно с помощью заголовков TCP пакета.
Что такое 1 соединение TCP
Прежде чем изучить структуру заголовка TCP пакета, разберёмся, что такое 1 TCP соединение — это поможет яснее понимать, что именно мы анализируем в Wireshark и сколько TCP соединений нам нужно искать. К примеру, сколько TCP соединений задействуется при открытии 1 страницы веб-сайта? Типичный веб-сайт состоит из 1 страницы HTML кода, нескольких страниц каскадных таблиц стилей CSS и JavaScript файлов, а также пары десятков файлов изображений. Так вот, для получения каждого из этих файлов создаётся новое TCP соединеие. Для каждого из этих соединений выполняется трёхэтапное рукопожатие — это к вопросу о том, какие издержки, «накладные расходы» несёт в себе TCP.
То есть при открытии страницы веб-сайта браузер делает первое TCP подключение и получает исходный код веб страницы. В данном коде браузер находит ссылки на файлы стилей, скриптов, картинок — для каждого из этого файлов запускается новое TCP соединение.
Поэтому при анализе трафика в Wireshark при открытии даже одной веб страницы вы увидите множество начатых и завершённых TCP соединений.
Заголовок TCP
- Порт источника — биты 0-15. Это порт источника пакета. Исходный порт изначально был связан напрямую с процессом в отправляющей системе. Сегодня мы используем хеш между IP-адресами и портами назначения и порта источника для достижения этой уникальности, которую мы можем привязать к одному приложению или программе.
- Порт назначения — биты 16-31. Это порт назначения пакета TCP. Как и в случае с портом-источником, он изначально был напрямую связан с процессом в принимающей системе. Сегодня вместо этого используется хеш, который позволяет нам иметь больше открытых соединений одновременно. Когда пакет получен, порты назначения и исходные порты возвращаются в ответе обратно к первоначально отправляющему хосту, так что порт назначения теперь является портом источника, а порт источника является портом назначения.
Порт источника и порт назначения не обязаны быть одинаковыми: к примеру, если делается запрос к 80-му порту сервера, то этот запрос может прийти, например, с порта 34054.
Номера портов на сервере могут использоваться как стандартные, так и произвольные.
- Порядковый номер (Sequence number) — биты 32-63. Поле порядкового номера используется для установки номера в каждом TCP-пакете, чтобы можно было правильно упорядочить поток TCP (например, пакеты приводятся к правильному порядку). Затем в поле ACK возвращается порядковый номер, чтобы подтвердить, что пакет был принят правильно.
Указывает на количество переданных байт, и каждый переданный байт полезных данных (payload) увеличивает это значение на 1.
Если установлен флаг SYN (идёт установление сессии), то поле содержит изначальный порядковый номер — ISN (Initial Sequence Number). В целях безопасности это значение генерируется случайным образом и может быть равно от 0 до 2 32 -1 (4294967295). Первый байт полезных данных в устанавливающейся сессии будет иметь номер ISN+1.
В противном случае, если SYN не установлен, первый байт данных, передаваемый в данном пакете, имеет этот порядковый номер.
- Номер подтверждения (Acknowledgment Number (ACK SN)) — биты 64-95. Это поле используется, когда мы подтверждаем определённый пакет, полученный хостом. Например, мы получаем пакет с одним установленным порядковым номером, и если с пакетом все в порядке, мы отвечаем пакетом ACK с номером подтверждения, равным оригинальному порядковому номеру.
Если установлен флаг ACK, то это поле содержит порядковый номер октета, который отправитель данного сегмента желает получить. Это означает, что все предыдущие октеты (с номерами от ISN+1 до ACK-1 включительно) были успешно получены.
Каждая сторона подсчитывает свой Sequence number для переданных данных и отдельно Acknowledgement number для полученных данных. Соответственно Sequence number каждой из сторон соответствует Acknowledgement number другой стороны.
- Длина заголовка (смещение данных) — биты 96-99. В этом поле указывается длина заголовка TCP пакета и где начинаются фактические данные (полезная нагрузка). Поле имеет размер в 4 бита и указывает заголовок TCP в 32-битных словах. Заголовок должен всегда заканчиваться чётной 32-битной границей, даже с различными установленными опциями (опции могут отсутствовать вовсе, либо их количество может различаться). Это возможно благодаря полю Padding в самом конце заголовка TCP.
Минимальный размер заголовка составляет 5 слов, а максимальный — 15 слов, что даёт минимальный размер 20 байтов и максимум 60 байтов, что позволяет использовать до 40 байтов опций в заголовке. Это поле получило такое имя (смещение данных) из-за того, что оно также показывает расположение фактических данных от начала сегмента TCP.
Итак, длина заголовка определяет смещение полезных данных относительно начала сегмента. Например, Data offset равное 1111 говорит о том, что заголовок занимает пятнадцать 32-битных слова (15 строк*32 бита в каждой строке/8 бит = 60 байт).
- Зарезервировано — биты 100-102. Эти биты зарезервированы для будущего использования.
- Флаги (управляющие биты)
- NS — бит 103. ECN-nonce — concealment protection
- CWR (Congestion Window Reduced) — бит 104. Поле «Окно перегрузки уменьшено» — флаг установлен отправителем, чтобы указать, что получен пакет с установленным флагом ECE
- ECE — бит 105. ECE (ECN-Echo) — Поле «Эхо ECN» — указывает, что данный узел способен на ECN (явное уведомление перегрузки) и для указания отправителю о перегрузках в сети (RFC 3168)
- URG — бит 106. Поле «Указатель важности» задействовано. Если установлено значение 0, не используется Urgent Pointer, если установлено значение 1, то используется Urgent Pointer.
- ACK — бит 107. Этот бит устанавливается для пакета, чтобы указать, что это ответ на другой полученный нами пакет, содержащий данные. Пакет подтверждения всегда отправляется, чтобы указать, что мы фактически получили пакет, и что он не содержит ошибок. Если этот бит установлен, исходный отправитель данных проверит номер подтверждения, чтобы увидеть, какой пакет фактически подтверждён, а затем выгрузит его из буферов.
- PSH — бит 108. Флаг PUSH используется для указания протоколу TCP на любых промежуточных хостах отправлять данные фактическому пользователю, включая реализацию TCP на принимающем хосте. Это протолкнёт все данные, независимо от того, где и сколько из окна TCP было уже передано.
- RST — бит 109. Флаг RESET установлен, чтобы сообщить другому концу разорвать TCP-соединение. Это делается в нескольких различных сценариях, основными причинами которых является то, что соединение по какой-то причине разорвалось, если соединение не существует или если пакет каким-то образом неправильный.
- SYN — бит 110. SYN (или синхронизация номеров последовательности) используется во время первоначального установления соединения. Он устанавливается в двух экземплярах соединения: начальный пакет, который открывает соединение, и ответный пакет SYN/ACK. Он никогда не должен использоваться за пределами этих случаев.
- FIN — бит 111. Бит FIN указывает, что у хоста, который отправил бит FIN, больше нет данных для отправки. Когда другой конец увидит бит FIN, он ответит FIN/ACK. Как только это будет сделано, хост, который первоначально отправил бит FIN, больше не сможет отправлять какие-либо данные. Однако другой конец может продолжать отправлять данные до тех пор, пока они не будет завершаться, и затем отправит пакет FIN обратно и дождётся окончательного FIN/ACK, после чего соединение отправляется в состояние CLOSED.
- Размер окна (Window Size) — биты 112-127. Window Size определяет количество байт данных (payload), после передачи которых отправитель ожидает подтверждения от получателя, что данные получены. Иначе говоря, получатель пакета располагает для приёма данных буфером длиной "размер окна" байт.
По умолчанию размер окна измеряется в байтах, поэтому ограничен 2 16 (65535) байтами. Однако благодаря TCP опции Window scale option этот размер может быть увеличен до 1 Гбайта. Чтобы задействовать эту опцию, обе стороны должны согласовать это в своих SYN сегментах.
- Контрольная сумма — биты 128-143. Поле контрольной суммы — это 16-битное дополнение к сумме всех 16-битных слов заголовка (включая псевдозаголовок) и данных. Если сегмент, по которому вычисляется контрольная сумма, имеет длину не кратную 16-битам, то длина сегмента увеличивается до кратной 16-ти, за счёт дополнения к нему справа нулевых битов заполнения. Биты заполнения (0) не передаются в сообщении и служат только для расчёта контрольной суммы. При расчёте контрольной суммы значение самого поля контрольной суммы принимается равным 0.
- Указатель важности (Urgent pointer) — биты 144-159. 16-битовое значение положительного смещения от порядкового номера в данном сегменте. Это поле указывает порядковый номер октета, которым заканчиваются важные (urgent) данные. Поле принимается во внимание только для пакетов с установленным флагом URG. Используется для внеполосных данных.
- Опции — биты 160-**. Могут применяться в некоторых случаях для расширения протокола. Иногда используются для тестирования. На данный момент в опции практически всегда включают 2 байта NOP (в данном случае 0x01) и 10 байт, задающих timestamps. Вычислить длину поля опции можно через значение поля смещения.
Поле Options является полем переменной длины и содержит необязательные заголовки, которые мы можем захотеть использовать. По сути, это поле всегда содержит 3 подполя. В начальном поле указывается длина поля «Параметры», во втором поле указывается, какие параметры используются, а затем у нас есть фактические параметры. Полный список всех опций TCP можно найти в опциях TCP.
- Заполнение (Padding) — биты**. Поле Заполнение дополняет заголовок TCP, пока весь заголовок не закончится на 32-разрядной границе. Это гарантирует, что часть данных пакета начинается с 32-разрядной границы, и данные в пакете не теряются. Заполнение всегда состоит только из нулей.
Сессия TCP
Рукопожатие TCP (установление подключения TCP)
Для установления соединения TCP использует трёхэтапное рукопожатие.
Подключение можно выполнить только если вторая сторона прослушивает порт, к которому будет выполняться подключение: к примеру, веб-сервер прослушивает порты 80 и 443. То есть это не охватывается рукопожатием, но прежде чем клиент попытается соединиться с сервером, сервер должен сначала подключиться к порту и начать прослушивать его, чтобы открыть его для соединений: это называется пассивным открытием. Как только пассивное открытие установлено, клиент может инициировать активное открытие. Для установления соединения происходит трёхэтапное (или трёхступенчатое) рукопожатие:
Первый этап, отправка пакета с включённым флагом SYN: активное открытие выполняется клиентом, отправляющим SYN на сервер. Клиент устанавливает порядковый номер сегмента на случайное значение A.
Обратите внимание, что по умолчанию Wireshark показывает относительное значение порядкового номера (Sequence number), чуть ниже вы также можете видеть реальное значение (показано как raw).
Второй этап, отправка пакета с включённым флагом SYN-ACK: В ответ сервер отвечает SYN-ACK. Номер подтверждения установлен на единицу больше принятого Порядкового номера (Sequence number), то есть A+1. Поскольку сервер также будет отправлять данные, то для себя он тоже выбирает Порядковый номер (Sequence number) первого пакета с данными, который будет другим случайным числом B.
Третий этап, отправка пакета с включённым флагом ACK: наконец, клиент отправляет ACK обратно на сервер. Порядковый номер устанавливается равным полученному значению подтверждения, то есть A+1, а номер подтверждения устанавливается на единицу больше, чем принятый порядковый номер, то есть B+1.
На этом этапе и клиент, и сервер получили подтверждение соединения. Шаги 1, 2 устанавливают параметр соединения (порядковый номер) для одного направления, и оно подтверждается. Шаги 2, 3 устанавливают параметр соединения (порядковый номер) для другого направления, и он подтверждается. Таким образом устанавливается полнодуплексная (двухсторонняя) связь.
Передача данных в TCP
PSH-ACK: Клиент отправляет запрос к серверу по HTTP протоколу, поскольку данные поместились в один сетевой пакет TCP, то он имеет флаг PSH, чтобы сервер не ждал продолжение получения данных, а отправил их веб-серверу для выполнения.
ACK: В ответ на принятую информацию сервер отправляет пакет ACK с номером успешно полученных данных.
PSH-ACK: Сервер обработал запрос и отправляет данные — веб страницу
ACK: клиент подтверждает, что данные получены
На последнем скриншоте:
1 — установка соединения
2 — передача данных
3 — завершение соединения
Завершение соединения
Фаза завершения соединения использует четырёхэтапное рукопожатие, причём каждая сторона соединения завершается независимо. Когда конечная точка хочет остановить свою половину соединения, она передаёт пакет FIN, который другой конец подтверждает пакетом с флагом ACK. Поэтому для типичного разрыва требуется пара сегментов FIN и ACK от каждой конечной точки TCP. После того, как сторона, отправившая первый FIN, ответила с последним ACK, она ожидает тайм-аута, прежде чем окончательно закрывает соединение, в течение которого локальный порт недоступен для новых соединений; это предотвращает путаницу из-за задержанных пакетов, доставляемых во время последующих соединений.
Соединение может быть «полуоткрытым», и в этом случае одна сторона завершила свою часть, а другая — нет. Завершившая сторона больше не может отправлять какие-либо данные в соединение, но другая сторона может. Завершающая сторона должна продолжить чтение данных, пока другая сторона также не завершит свою работу.
Также возможно разорвать соединение трёхэтапным рукопожатием, когда хост A отправляет FIN, а хост B отвечает FIN&ACK (просто объединяет 2 шага в один), а хост A отвечает ACK.
Некоторые операционные системы, такие как Linux и H-UX, реализуют полудуплексную последовательность закрытия в стеке TCP. Если хост активно закрывает соединение, но при этом остаются непрочитанными входящие данные, хост отправляет сигнал RST (потеря всех полученных данных) вместо FIN. Это гарантирует приложению TCP, что удалённый процесс прочитал все переданные данные, ожидая сигнала FIN, прежде чем он активно закроет соединение. Удалённый процесс не может различить сигнал RST для прерывания соединения и потери данных. Оба вызывают удалённый стек, чтобы потерять все полученные данные.
Как можно увидеть на скриншоте, завершение TCP соединения также происходит как (Linux с последним ядром):
Клиент: FIN-ACK
Сервер: FIN-ACK
Клиент: ACK
Состояния клиента и сервера
| Состояния сеанса TCP | |
|---|---|
| CLOSED | Начальное состояние узла. Фактически фиктивное |
| LISTEN | Сервер ожидает запросов установления соединения от клиента |
| SYN-SENT | Клиент отправил запрос серверу на установление соединения и ожидает ответа |
| SYN-RECEIVED | Сервер получил запрос на соединение, отправил ответный запрос и ожидает подтверждения |
| ESTABLISHED | Соединение установлено, идёт передача данных |
| FIN-WAIT-1 | Одна из сторон (назовём её узел-1) завершает соединение, отправив сегмент с флагом FIN |
| CLOSE-WAIT | Другая сторона (узел-2) переходит в это состояние, отправив, в свою очередь сегмент ACK и продолжает одностороннюю передачу |
| FIN-WAIT-2 | Узел-1 получает ACK, продолжает чтение и ждёт получения сегмента с флагом FIN |
| LAST-ACK | Узел-2 заканчивает передачу и отправляет сегмент с флагом FIN |
| TIME-WAIT | Узел-1 получил сегмент с флагом FIN, отправил сегмент с флагом ACK и ждёт 2*MSL секунд, перед окончательным закрытием соединения |
| CLOSING | Обе стороны инициировали закрытие соединения одновременно: после отправки сегмента с флагом FIN узел-1 также получает сегмент FIN, отправляет ACK и находится в ожидании сегмента ACK (подтверждения на свой запрос о разъединении) |
Описание данных состояний позволяет лучше понимать информацию, которую показывают программы о состоянии сети, такие как netstat и ss (смотрите также «Как проверить открытые порты на своём компьютере. Что означают 0.0.0.0, :*, [::], 127.0.0.1. Как понять вывод NETSTAT»).
Фильтры Wireshark для TCP
Чтобы увидеть только трафик TCP:
Показать трафик, источником или портом назначения которого является определённый порт, например 8080:
Показать трафик, источником которого является порт 80:
Показать трафик, который отправляется службе, прослушивающей порт 80:
Показать TCP пакеты с включённым флагом SYN:
Показать TCP пакеты с включённым флагом SYN и отключённым флагом ACK:
Аналогично и для других флагов:
- SYN
- ACK
- RST
- FIN
- CWR
- ECE
- URG
- PSH
- NS
Также можно использовать синтаксис вида tcp.flags == 0x0XX, например:
- FIN это tcp.flags == 0x001
- SYN это tcp.flags == 0x002
- RST это tcp.flags == 0x004
- ACK это tcp.flags == 0x010
- Установленные одновременно ACK и FIN это tcp.flags == 0x011
- Установленные одновременно ACK и SYN это tcp.flags == 0x012
- Установленные одновременно ACK и RST это tcp.flags == 0x014
Длина заголовка (смещение данных):
Пакеты с установленными зарезервированными битами:
Вычесленный размер окна:
Фактор масштабирования размера окна:
tcp.window_size_value — это необработанное значение размера окна, считываемое непосредственно из заголовка TCP, тогда как tcp.window_size — это вычисленный размер окна, который основан на том, применимо ли масштабирование окна или нет. Если масштабирование окна не используется или коэффициент масштабирования равен 1 или неизвестно, применимо ли масштабирование окна или нет, потому что трёхэтапное рукопожатие TCP не было захвачено, тогда эти два значения будут одинаковыми. С помощью tcp.window_size_scalefactor вы можете определить, какое из этих условий применимо — если его значение равно -1, то оно неизвестно, если его значение равно -2, тогда масштабирование окна не используется, а все остальные значения представляют фактический размер фактора масштабирования окна.
Чтобы показать пакеты, содержащие какую либо строку, например, строку hackware:
Следовать потоку TCP с номером X:
Фильтровать по номеру потока:
Показать повторные отправки пакетов. Помогает прослеживать замедление производительности приложений и потери пакетов:
Этот фильтр выведен проблемные пакеты (потерянные сегменты, повторную отправку и другие. Этот фильтр проходят пакеты TCP Keep-Alive, но они не являются показателем проблем.
Фильтры для оценки качества сетевого подключения.
Следующие характеристики относятся к TCP фреймам. Причём они не основываются на заголовках фрейма — рассматриваемые характеристики (пропуск данных, дубли) присвоены программой Wireshark исходя из анализа.
Фильтр выводит информацию о фреймах с флагом ACK, которые являются дублями. Большое количество таких фреймов может говорить о проблемах связи:
Фильтр показа фреймов для которых не захвачен предыдущий сегмент:
Это нормально в начале захвата данных — поскольку информация перехватывается не с самого начала сессии.
Для показа фреймов, которые являются ретрансмиссией (отправляются повторно):
Вывод фреймов, которые получены не в правильном порядке:
Виды сканирований Nmap
Мы рассмотрели механизм рукопожатия TCP, напомним его структуру:
- Клиент: SYN
- Сервер: SYN-ACK
- Клиент: ACK
Знаменитый сканер портов Nmap по умолчанию выполняет сканирования с использованием полуотрытых соединений, или его ещё называют SYN сканированием. На самом деле, это не что иное, как отправленный пакет с включённым флагом SYN — то есть Nmap инициирует рукопожатие TCP. Если в ответ приходит пакет с флагами SYN-ACK (то есть удалённый хост отправляет свою часть рукопожатия), то это означает, что порт открыт. Если удалённый хост отвечает пакетом с флагом RST-ACK, то это означает, что порт закрыт.
Такой метод, с одной стороны, является универсальным — любой открытый порт обязательно должен ответить пакетом с флагами SYN-ACK, поскольку это стандарт транспортного протокола TCP. Но при этом Nmap не завершает рукопожатие, то есть не создаётся полноценное соединение и приложение, которое прослушивает просканированный порт, никогда не узнает об этом неудачном TCP рукопожатии, и этот факт не отобразиться в журналах этого приложения.
Пример сканирования портов:
На следующем скриншоте мы можем видеть отправленные и полученные пакеты:
Первая группа пакетов (выделена прямоугольником) — пинг хоста, чтобы определить, доступен ли он. Также на этапе доступности хоста делается запрос к портам 80 и 443 (хотя порт 443 не указан для сканирования), видимо, также для подтверждения того, что хост онлайн.
Если от порта получен пакет SYN-ACK (сервер готов к установке соединения), то Nmap отвечает пакетом с флагом RST для обрыва начатого рукопожатия.
Вторая группа — они отмечены серым и зелёным — это непосредственно сканирование портов — это пакеты с флагом SYN. Серым отмечены те, которые прислали ответ RST-ACK (порт закрыт), а зелёным т е, которые прислали ответ SYN-ACK (порт открыт).
Пакеты RST-ACK, а также пакеты RST (от Nmap) помечены красным.
Как можно увидеть, техника очень простая и использует самые базовые возможности трансопртного протокола TCP.
Кроме этого метода, Nmap поддерживает ещё несколько типов сканирования:
Если вы хотите узнать об этих опциях и типах сканирвоания подробнее, то рекомендуется изучить их на справочной странице Nmap: https://kali.tools/?p=1317
Теперь, когда понятна суть сканирований портов, можно предложить меры по защите сервера от сканирований. Если ваш сервер предназначен принимать входящие соединения (например, это веб сервер с SSH), то на 100% защититься от сканирований портов нельзя, поскольку для полуоткрытых соединений используются «легальные» TCP пакеты с флагом SYN, которые являются первой частью рукопожатий. Тем не менее в iptables или fail2ban можно настроить примерно такое правило: «если от одного удалённого хоста поступило более 10 SYN пакетов за указанный промежуток времени, то отклонять его последующие попытки подключения». Это затруднит или даже сделает невозможным массовое сканирование портов на вашем сервере.
Если у вас настроен контроль доступа по IP, то можно запретить SYN пакеты от любого хоста, кроме разрешённых IP, — в этом случае посторонние не только не смогут подключаться, но и не смогут узнать, что порт на самом деле открыт.
Примеры iptables
[БУДЕТ ДОБАВЛЕНО ПОЗЖЕ]
Протокол UDP
Если вы смогли разобраться с TCP и его заголовками, то с UDP вам будет совсем просто.
Протокол пользовательских дейтаграмм (UDP) — это очень простой протокол. Он был разработан для обеспечения очень простой передачи данных без какого-либо обнаружения ошибок. Это так называемый stateless (то есть «без состояния») протокол, это отличает его от протокола TCP, в котором есть понятие соединения (stateful), включающее в себя создания подключения (трёхэтапное рукопожатие) и в котором передача данных выполняется только в рамках данного подключения. Соответственно, для протокола UDP не предусмотрены различные состояния клиента и сервера.
Однако он очень хорошо подходит для приложений типа запрос/ответ, таких как, например, DNS и т. д., поскольку мы знаем, что если мы не получим ответ от DNS-сервера, запрос где-то был потерян. Иногда также стоить использовать протокол UDP вместо TCP, например, когда мы хотим только обнаружение ошибок/потерь, но не заботимся о последовательности пакетов. Это устраняет некоторые издержки, связанные с протоколом TCP.
Природа UDP как протокола без сохранения состояния также полезна для серверов, отвечающих на небольшие запросы от огромного числа клиентов, например DNS и потоковые мультимедийные приложения вроде IPTV, Voice over IP, протоколы туннелирования IP и многие онлайн-игры.
Что такое 1 соединение UDP
Для UDP пакетов понятие «соединение» неправильное, поскольку отправляется один пакет без установки соединения. Если требуется передать поток данных, то отправляется множество UDP пакетов, которые хотя и могут иметь одну общую задачу, с точки зрения транспортного протокола каждый из них является независимым.
В ответ также может прийти один или несколько пакетов UDP. Они приходят на тот же порт, с которого был отправлен исходный UDP пакет — это позволяет определить, что данная датаграмма является ответной на отправленную ранее.
Тем не менее при открытом UDP порте состояние сервера становится LISTEN (сервер ожидает запросов установления соединения от клиента). Также UDP соединение может иметь статус UCONN или ESTAB.
Как можно увидеть, UDP пакет отправлен с порта 42044:
Ответный UDP пакет также пришёл на порт 42044:
Если сравнить с TCP, то минимальное количество пакетов для отправки запроса и получения информации — 10, а для UDP минимальное количество пакетов для отправки запроса и получения информации — 2.
Заголовок UDP
Можно сказать, что заголовок UDP представляет собой очень упрощённый заголовок TCP. Он содержит порты назначения, порты источника, длину заголовка и контрольную сумму, как показано на рисунке ниже.
- Исходный порт — биты 0-15. Это порт источника пакета, описывающий, куда должен быть отправлен ответный пакет. Он может фактически быть установлено на ноль, если значение порта не применимо. Например, иногда нам не требуется ответный пакет, то тогда пакет может быть установлен на нулевой порт источника. В большинстве реализаций он установлен на некоторый номер порта.
- Порт назначения — биты 16-31. Порт назначения пакета. Это требуется для всех пакетов, в отличие от порта источника пакета.
Как и с протоколом TCP — для сервера обычно используется один из стандартных портов (например, порт 53 для DNS серверов), а порт источника выбирается произвольно для каждого соединения, обычно это номера портов с большим номером (десятки тысяч).
- Длина — биты 32-47. Поле длины указывает длину всего пакета в октетах, включая заголовок и части данных. Самый короткий возможный пакет может быть длиной 8 октетов.
Поле, задающее длину всей датаграммы (заголовка и данных) в байтах. Минимальная длина равна длине заголовка — 8 байт. Теоретически, максимальный размер поля — 65535 байт для UDP-датаграммы (8 байт на заголовок и 65527 на данные). Фактический предел для длины данных при использовании IPv4 — 65507 (помимо 8 байт на UDP-заголовок требуется ещё 20 на IP-заголовок).
- Контрольная сумма — биты 48-63. Контрольная сумма — это та же контрольная сумма, что и в заголовке TCP, за исключением того, что она содержит другой набор данных. Другими словами, это дополнение к сумме дополнительных частей заголовка IP, всего заголовка UDP, данных UDP и дополнения нулями в конце, когда это необходимо.
Поле контрольной суммы используется для проверки заголовка и данных на ошибки. Если сумма не сгенерирована передатчиком, то поле заполняется нулями. Поле не является обязательным для IPv4.
Фильтры Wireshark для UDP
Чтобы увидеть только трафик UDP:
Для UDP не используются флаги. Для этого протокола можно только указать порт.
Показать трафик, источником которого является порт 53:
Показать трафик, который отправляется службе, прослушивающей порт 53:
UDP пакет, в котором встречается определённая строка, например, строка hackware:
Порт назначения ИЛИ исходный порт:
Время между пакетами (для выявления проблем сети):
Номер потока (запрос-ответ):
Сравнение UDP и TCP
TCP — ориентированный на соединение протокол, что означает необходимость «рукопожатия» для установки соединения между двумя хостами. Как только соединение установлено, пользователи могут отправлять данные в обоих направлениях.
- Надёжность — TCP управляет подтверждением, повторной передачей и тайм-аутом сообщений. Производятся многочисленные попытки доставить сообщение. Если оно потеряется на пути, сервер вновь запросит потерянную часть. В TCP нет ни пропавших данных, ни (в случае многочисленных тайм-аутов) разорванных соединений.
- Упорядоченность — если два сообщения последовательно отправлены, первое сообщение достигнет приложения-получателя первым. Если участки данных прибывают в неверном порядке, TCP отправляет неупорядоченные данные в буфер до тех пор, пока все данные не могут быть упорядочены и переданы приложению.
- Тяжеловесность — TCP необходимо три пакета для установки сокет-соединения перед тем, как отправить данные. TCP следит за надёжностью и перегрузками.
- Потоковость — данные читаются как поток байтов, не передается никаких особых обозначений для границ сообщения или сегментов.
UDP — более простой, основанный на сообщениях протокол без установления соединения. Протоколы такого типа не устанавливают выделенного соединения между двумя хостами. Связь достигается путём передачи информации в одном направлении от источника к получателю без проверки готовности или состояния получателя. В приложениях для голосовой связи через интернет-протокол (Voice over IP, TCP/IP) UDP имеет преимущество над TCP, в котором любое «рукопожатие» помешало бы хорошей голосовой связи. В VoIP считается, что конечные пользователи в реальном времени предоставят любое необходимое подтверждение о получении сообщения.
Протоколы сетевого взаимодействия TCP/IP
Протоколы сетевого взаимодействия TCP/IP являются результатом эволюционного развития протоколов глобальной вычислительной сети ARPANET.
Работы по созданию сети ARPANET были начаты рядом университетов США и фирмой BBN в 1968 г. В 1971 г. сеть была введена в регулярную эксплуатацию и обеспечивала для всех своих узлов три основные услуги:
- интерактивный вход пользователя на удаленный узел;
- передача файлов между узлами сети;
- электронная почта.
Все эти средства базировались на транспортных услугах предоставляемых программой управления сети NCP (Network Control Program), реализующей свой внутренний набор протоколов.
Накопленный к 1974 г. опыт эксплуатации сети ARPANET выявил многие недостатки протоколов NCP и позволил определить основные требования к новому набору протоколов, получившему название TCP/IP:
- независимость от среды передачи сообщений;
- возможность подключения к сети ЭВМ любой архитектуры;
- единый способ организации соединения между узлами в сети;
- стандартизация прикладных протоколов.
Широко используемая ныне версия 4 протоколов TCP/IP была стандартизирована в 1981 г. в виде документов, называемых RFC (Request For Comment). Полный переход сети ARPANET на новые протоколы был завершен в 1982 г. Эта сеть сыграла роль "зародыша" всемирной сети Internet, построенной на базе протоколов TCP/IP.
Реализация протоколов TCP/IP оказалась наиболее удачной в версиях BSD4.2 и BSD4.3 операционной системы UNIX. Эта реализация является эталоном (станартом "de facto") для всех последующих.
Примечание. Первичным сервером хранения всех RFC является узел nisc.sri.com (доступ через анонимный FTP).
1. Соотношение между OSI/ISO и TCP/IP
В 1984 г. международная стандартизирующая организация ISO предложила модель взаимодействия открытых систем OSI (Open System Interconnection), являющуюся удобным средством описания стеков протоколов.
На рис. 1.1 представлено соотношение четырехуровневой архитектуры протоколов TCP/IP и семиуровневой архитектуры OSI.
Объединение канального и физического уровней модели OSI в единый сетевой уровень TCP/IP было обусловлено требованием независимости от используемой среды передачи данных. Дело в том, что функции протоколов канального и физического уровней реализуются в настоящее время , как правило, едиными техническими средствами (сетевыми контроллерами).
Согласно терминологии TCP/IP элементы сетевого уровня называются подсетями (subnetworks). Идеология TCP/IP допускает, чтобы в качестве "подсетей" выступали реальные сети с их собственными стеками протоколов, узлами, шлюзами и т.п.
Внимание. Далее в данном учебном пособии для обозначения уровней стека протоколов используется терминология TCP/IP, а не OSI/ISO (если это не оговорено особо).
Внимание. В данном учебном пособии термин "шлюз" используется как обобщающий для понятий "маршрутизатор" (router), "мост" (bridge) и, собственно, "шлюз" (gateway).
2. Архитектура протоколов TCP/IP
На рис. 2.1 представлена архитектура основных протоколов TCP/IP, используемых на трех нижних уровнях стека.
Краеугольным камнем всей архитектуры является межсетевой протокол IP ( Internet Protocol ). С его помощью реализуется адресация узлов сети и доставка данных. Межсетевой протокол управляющих сообщений ICMP ( Internet Control Message Protocol ) предназначен для передачи диагностической информации и сообщений об ошибках в работе сети.
Примечание. Протокол ICMP отнесен к межсетевому уровню условно, т.к., с одной стороны, он пользуется возможностями протокола IP для транспортировки собственных данных, но, с другой стороны, сам для транспортировки данных пользователя не применяется.
Двумя основными протоколами транспортного уровня являются надежный протокол управления передачей данных TCP ( Transmission Control Protocol ) и быстрый протокол дэйтаграмм пользователя UDP ( User Datagram Protocol ). TCP реализует сетевое взаимодействие в режиме с установлением логического (виртуального) соединения, а UDP — без оного.
Функции каждого протокола реализуются компонентой программного обеспечения (обычно входящей в состав операционной системы), которую будем называть модулем . Взаимодействие модулей соседних уровней осуществляется через стандартизированный интерфейс, имеющий, как правило, процедурный характер.
Внимание. На каждом уровне стека протоколов TCP/IP обмен данными ведется блоками данных конечной длины. К сожалению, отсутствует устоявшаяся терминология в обозначении этих блоков. В данном учебном пособии названия блоков данных зависят от уровня стека протоколов, как это показано ниже.
3. Межсетевой протокол IP
Межсетевой протокол IP специфицирован в RFC 791. Его основные характеристики перечислены ниже:
- реализует обмен информации пакетами, которые будем называть IP-сегментами (максимальный размер IP-сегмента — 65535 байт);
- является протоколом взаимодействия без установления логического соединения;
- для адресации узлов сети используется адрес длиной 4 байта;
- обеспечивает в случае необходимости фрагментацию IP-сегментов;
- IP-сегменты имеют конечное время жизни в сети;
- не гарантирует надежность доставки IP-сегментов адресату;
- не имеет средств управления интенсивностью передачи IP-сегментов посылающей стороной (flow control);
- не гарантирует правильную последовательность IP-сегментов на принимающей стороне.
3.1. Заголовок IP-сегмента
На рис. 3.1 приведен формат заголовка IP-сегмента.
4-хбитовое поле, содержащее номер версии протокола IP (номер текущей версии равен 4);
4-хбитовое поле, содержащее длину заголовка IP-сегмента в 32-битных словах. Минимальная (и типичная) длина заголовка — пять слов.
байт, содержащий набор критериев, определяющих тип обслуживания IP-сегментов. Детальное описание отдельных битов дано ниже:
- биты 0. 2 — приоритет (precedence — предпочтение) данного IP-сегмента;
- бит 3 — требование ко времени задержки (delay) передачи IP-сегмента (0 — нормальная, 1 — низкая задержка);
- бит 4 — требование к пропускной способности (throughput) маршрута, по которому должен отправляться IP-сегмент (0 — низкая, 1 — высокая пропускная способность);
- бит 5 — требование к надежности (reliability) передачи IP-сегмента (0 -нормальная, 1 — высокая надежность);
- биты 6. 7 — зарезервированы.
На практике в большинстве реализаций протокола IP данное поле почти всегда равно 0, в UNIX-реализациях это поле не используется вовсе.
двухбайтовое поле, содержащее длину (в байтах) всего IP-сегмента, включая длину заголовка. Максимальная длина IP-сегмента (включая заголовок) — 65535 байт. Спецификация IP протокола устанавливает, что что любой узел сети должен быть способен обрабатывать IP-сегменты длиной, по крайней мере, не менее 576 байт (что соответствует 512 байтам данных при возможной длине заголовка до 64 байт). На практике же узлы сети могут обрабатывать IP-сегменты много длинее, чем 576 байт (как правило, допустимая длина IP-сегмента связана с максимальной длиной кадра нижележащего сетевого уровня).
двухбайтовое поле, содержащее уникальный идентификатор IP-сегмента, присваиваемый ему посылающим узлом. Это поле используется для распознавания фрагментов одного IP-сегмента (в ситуациях, когда в ходе перемещения по глобальной сети единый IP-сегмент был разбит на несколько фрагментов по причине его недопустимо большой длины).
биты, используемые при обработке фрагментированных IP-сегментов.
Если бит DF (Don’t Fragment) установлен в 1, то это означает, что IP-сегмент не может быть разбит на фрагменты ни при каких условиях (даже, если он не может быть передан без этого далее к адресату и должен быть уничтожен).
Бит MF (More Fragments) указывает, является (MF=0) или нет (MF=1) данный IP-"подсегмент" последним в цепочке IP-"подсегментов", в которую был преобразован (фрагментирован) исходный IP-сегмент.
Алгоритм фрагментации описан ниже в разделе "Фрагментация IP-сегментов".
13-битное поле, используемое только в IP-сегменте, являющемся фрагментом (IP-фрагментом) другого (исходного) IP-сегмента. Это поле содержит смещение данных, содержащихся в IP-фрагменте, по отношению к началу данных исходного IP-сегмента. Смещение измеряется в восьмибайтных единицах, поэтому 13 битов достаточно для представления смещения в IP-сегменте максимальной возможной длины (8 * 2^13 — 1 = 65535).
однобайтовое поле, заполняемое создающим IP-сегмент узлом сети количеством единиц времени жизни IP-сегмента в сети. RFC 791 специфицирует в качестве этих единиц секунды и требует, чтобы каждый транзитный узел сети, через который проходит IP-сегмент, уменьшал содержимое этого поля по крайней мере на 1 (даже при условии, что обработка сегмента на самом деле заняла меньше одной секунды). Таким образом, на практике, время жизни ( TTL — Time To Live) — это максимальное количество узлов, которое может пройти до своего уничтожения IP-сегмент.
Каждый IP-модуль на любом узле сети обязан уничтожать IP-сегменты, для которых поле "время жизни" стало равным нулю. Этим предотвращается появление в сети IP-сегментов, "блуждающих" по ней бесконечное время. При этом узлу-источнику уничтоженного IP-сегмента посылается ICMP-сегмент, извещающий об этом событии.
В UNIX-реализациях, как правило, это поле заполняется источником IP-сегмента числом из диапазона 15. 30.
поле размером в байт, содержащее идентификатор протокола более высокого (обычно, транспортного) уровня, для которого предназначены данные IP-сегмента. Ниже приведены идентификаторы для ряда протоколов.
Контрольная сумма заголовка
двухбайтовое поле, содержащее контрольную сумму заголовка IP-сегмента (обращаем внимание, что для данных IP-сегмента контрольная сумма не подсчитывается; контролировать данные — задача протоколов транспортного уровня).
Поскольку заголовок IP-сегмента содержит поле "время жизни", изменяющее свое значение в каждом узле, через который следует IP-сегмент, то для вычисления контрольной суммы должен использоваться эффективный (а, следовательно, простой алгоритм). Во всех протоколах, входящих в архитектуру TCP/IP, используется так называемая Internet-контрольная сумма, которая представляет собой дополнение 16-битной суммы всех 16-битных слов контролируемой информации.
Адрес источника и адрес приемника
четырехбайтовые IP-адреса узлов сети. Подробно структура IP-адреса описана ниже в "IP-адрес".
Дополнительные данные заголовка
последовательность полей произвольной длины, описывающих необязательные данные заголовка. Такие данные используются для специальных целей (управление сетью, секретность и т.п.) и кратко описаны ниже в "Дополнительные данные IP-заголовка".
не имеющие смысла данные, включаемые в заголовок только для выравнивания его длины до границы четырехбайтового слова.
3.2. IP-адрес
IP-адрес представляет собой четырехбайтовое число, старшие (крайние левые) биты которого определяют класс IP-адреса. Для классов A , B и C четыре байта адреса делятся между идентификатором (номером) сети и идентификатором (номером) узла в сети как это показано на рис. 3.2.
Сети классов A, B и C абсолютно равноправны и отличаются лишь допустимым количеством узлов в них. Идентификаторы узлов, состоящие из одних нулевых или единичных битов имеют специальный смысл:
- IP-адрес с нулевым идентификатором узла используется для обозначения сети в целом;
- IP-адрес с идентификатор узла в виде единичных битов является широковещательным (broadcast) адресом.
IP-адреса принято записывать в так называемой "точечной нотации" — в виде последовательности разделенных точками четырех десятичных (или шестнадцатиричных с префиксом 0x) чисел, представляющих значения отдельных байтов.
Каждый узел в сети имеет, по крайней мере, один уникальный IP-адрес.
Кроме классов A, B и C существуют еще два класса IP-адресов — D и E (см. рис. 3.3).
Класс D используется для организации многопунктового ( multicast ) режима посылки сообщений: IP-сегмент, посылаемый по по IP-адресу класса D, доставляется всем узлам сети, имеющим указанный идентификатор группы узлов. Описание данного режима дано в RFC 1112.
Примечание. Не все современные реализации протоколов TCP/IP поддерживают многопунктовое вещание.
Для обеспечения гибкости при создании и администрировании сетей различного размера в 1985 г. было введено понятие "подсеть" (RFC 950), позволяющее использовать один и тот же IP-адрес классов A,B или C для разных подсетей.
Такая возможность обеспечивается специальной битовой маской (netmask) , ассоциированной с IP-адресом и определяющей распределение битов IP-адреса между идентификатором подсети и идентификатором узла.
Пусть, например, IP-адрес класса C 194.85.36.0 планируется использовать для организации четырех подсетей. Это потребует выделения двух битов из части IP-адреса, относящейся к идентификатору узла. Такое "перепланирование" структуры IP-адреса реализуется сетевой маской 255.255.255.192, где десятичное 192 — это двоичное 11000000.
Эта сетевая маска формирует IP-адрес не из двух, а из трех комронент:
- идентификатор сети (24 бита);
- идентификатор подсети (2 бита);
- идентификатор узла (6 бит).
Каждая из четырех образованных подсетей может иметь до 62 узлов с идентификаторами от 1 до 62, идентификатор узла с номером 63 является широковещательным идентификатором для подсети.
Примечание. Для идентификатора подсети можно выделять только старшие (самые левые) биты из части IP-адреса, отводимой под идентификатор узла.
Примечание. Возможность разбиения сетей на подсети обусловливается, в первую очередь, средствами маршрутизации IP-сегментов, а не средствами IP-модулей, формирующих и обрабатывающих IP-сегменты.
Примечание. Некоторые современные реализации протоколов маршрутизации для TCP/IP позволяют выделять "подподсети" в подсетях.
3.3. Фрагментация IP-сегментов
Для того, чтобы существовала возможность передачи IP-сегментов через сети различного типа, межсетевой протокол обеспечивает адаптацию их размера к требованиям каждой сети. Это дает возможность, например, IP-сегментам, порожденным в сети на базе Ethernet (максимальный размер кадра — 1526 байт), беспрепятственно перемещаться до адресата по сети на базе X.25 (максимальный размер кадра — 128 байт). Изменение размера IP-сегмента в процессе перемещения по сети может быть связано и с соображениями эффективности передачи.
Изменение размера IP-сегмента реализуется механизмом, называемым фрагментацией. IP-модуль на любом узле сети должен иметь возможность:
- разбивать полученный им IP-сегмент на IP-фрагменты необходимого размера перед их передачей через конкретную сеть;
- восстанавливать исходный IP-сегмент из получаемых им IP-фрагментов.
Каждый IP-фрагмент представляет собой полноценный IP-сегмент со своим собственным IP-заголовком. Однако заголовки всех IP-фрагментов содержат одинаковый идентификатор, совпадающий с идентификатором исходного IP-сегмента. Это позволяет распознавать все IP-фрагменты, относящиеся к одному исходному IP-сегменту.
IP-фрагменты в своих заголовках содержат поле "Смещение фрагмента", описывающее смещение данных IP-фрагмента в данных исходного IP-сегмента. Это поле позволяет корректно восстановить данные исходного IP-сегмента в принимающем IP-фрагменты узле даже в ситуации, когда IP-фрагменты приходят в порядке, от порядка их посылки (такое вполне возможно, т.к. IP-фрагменты могут следовать от источника к адресату по разным маршрутам).
Рассмотрим процесс фрагментации более подробно на следующем примере. IP-модуль на некотором узле получил IP-сегмент с идентификатором 9876 и данными длиной 300 байт (при этом бит запрета фрагментации DF установлен в 0). Этот IP-сегмент должен быть передан дальше к адресату через сеть, максимальный размер кадра которой равен 128 байтам.
Рис. 3.4 схематично представляет разбиение исходного IP-сегмента на 3 IP-фрагмента.
IP-фрагмент 1 содержит в своем заголовке следующую информацию:
- идентификатор — 9876;
- длина заголовка — 5 (четырехбайтных слов);
- длина сегмента — 124 (байт);
- бит MF — 1;
- смещение фрагмента — 0 (восьмибайтных единиц).
IP-фрагмент 2 содержит в своем заголовке следующую информацию:
- идентификатор — 9876;
- длина заголовка — 5 (четырехбайтных слов);
- длина сегмента — 124 (байт);
- бит MF — 1;
- смещение фрагмента — 13 (восьмибайтных единиц).
IP-фрагмент 3 содержит в своем заголовке следующую информацию:
- идентификатор — 9876;
- длина заголовка — 5 (четырехбайтных слов);
- длина сегмента — 112 (байт);
- бит MF — 0;
- смещение фрагмента — 26 (восьмибайтных единиц).
Заметим, что т.к. смещение фрагмента измеряется в восьмибайтных единицах, то длина данных в каждом IP-фрагменте (кроме последнего в цепочке) обязательно должна быть кратна 8. Вот почему в нашем примере это 104 байта (13 восьмибайтных единиц), а не 108, как допускает максимальная длина кадра в 128 байт (128 — 20 = 108, где 20 — длина заголовка).
IP-модуль на принимающем IP-фрагменты узле в ситуации, когда он должен транслировать IP-сегмент далее по сети, имеет три варианта действий с фрагментами:
- переслать IP-фрагменты далее неизменными;
- разбить (если в этом есть необходимость) полученные IP-фрагменты на более короткие IP-фрагменты;
- восстановить исходный IP-сегмент из фрагментов.
В работе с IP-фрагментами на принимающей стороне используется специальный таймер, который с приходом первого фрагмента IP-сегмента устанавливается в исходное состояние (для UNIX-реализаций это, обычно, 30 сек) и начинает обратный счет. До момента обнуления таймера должны прийти все IP-фрагменты, относящиеся к этому сегменту. Если этого не произойдет, то все частично полученные данные IP-сегмента сбрасываются, а сам IP-сегмент считается утерянным.
3.4. Дополнительные данные IP-заголовка
Ниже кратко описываются дополнительные данные, которые могут включаться в IP-заголовок в случае необходимости.
список IP-адресов узлов сети, через которые должен следовать до адресата IP-сегмент. Предписываемый маршрут может быть "строгим" или "мягким". В первом случае IP-сегмент должен следовать строго только по указанным в списке узлам сети, во втором — допустимо прохождение через любые промежуточные узлы, не указанные в списке.
список IP-адресов узлов сети, которые посетил IP-сегмент по пути к адресату. Каждый транзитный узел, через который следует IP-сегмент, помещает в этот список свой IP-адрес.
Временные метки (time stamp)
список моментов времени прохождения IP-сегмента через узлы сети, составляющие маршрут.
указание на обработку IP-сегмента в соответствии с требованиями безопасности (RFC 1038). Эта возможность имеется только в нескольких (военных) реализациях TCP/IP.
указание на завершение дополнительных данных IP-заголовка.
Каждый элемент дополнительных данных представляет собой
- либо однобайтовый идентификатор дополнительных данных (например, "флаг окончания");
- либо комбинацию однобайтового идентификатора, поля длины и данных (например, "предписываемый маршрут").
Для дополнительных данных, пополняемых в ходе продвижения IP-сегмента по сети (например, "пройденный маршрут"), источник IP-сегмента должен зарезервировать место необходимого объема в IP-заголовке. Такой подход обеспечивает упрощение (а, следовательно, и ускорение) обработки IP-сегмента в узлах маршрута.
RFC 1063 (1988 г.) предлагает механизм определения оптимального размера IP-сегмента, при посылке его к определенному адресату. Этот механизм использует дополнительные данные IP-заголовка, называемые probe MTU (probe Maximum Transfer Unit — тестовый максимальный блок передачи). Каждый узел в маршруте IP-сегмента, содержащего такие дополнительные данные, сравнивает MTU следующей по маршруту сети с MTU, содержащемся в заголовке, и заменяет в нем старое значение на новое, если новое оказывается меньше. Конечный адресат IP-сегмента возвращает определенное таким образом значение источнику IP-сегмента. Использование в дальнейших посылках найденного размера IP-сегментов, позволяет избежать их фрагментации. Этот механизм широкого распространения еще не получил.
Примечание. Понятие MTU подробно рассматривается в "Протоколы сетевого уровня" .
4. Протокол управления передачей TCP
Протокол управления передачей TCP (Transmission Control Protocol) является протоколом транспортного уровня и базируется на возможностях, предоставляемых межсетевым протоколом IP. Основная задача TCP — обеспечение надежной передачи данных в сети. Его транспортный адрес в заголовке IP-сегмента равен 6. Описание протокола TCP дано в RFC 793.
Его основные характеристики перечислены ниже:
- реализует взаимодействие в режиме с установлением логического (виртуального) соединения;
- обеспечивает двунаправленную дуплексную связь;
- организует потоковый (с точки зрения пользователя) тип передачи данных;
- дает возможность пересылки части данных, как "экстренных";
- для идентификации партнеров по взаимодействию на транспортном уровне использует 16-битовые "номера портов";
- реализует принцип "скользящего окна" (sliding window) для повышения скорости передачи;
- поддерживает ряд механизмов для обеспечения надежной передачи данных.
Несмотря на то, что для пользователя передача данных с использованием протокола TCP выглядит как потоковая, на самом же деле обмен между партнерами осуществляется посредством пакетов данных, которые мы будем называть "TCP-пакетами".
4.1. Заголовок TCP-пакета
На рис. 4.1 приведен формат заголовка TCP-пакета.
Порт источника и порт приемника
16-битовые поля, содержащие номера портов, соответственно, источника и адресата TCP-пакета. Подробное описание понятия "номер порта" дано в "Номер порта".
Номер в последовательности (sequence number)
32-битовое поле, содержимое которого определяет (косвенно) положение данных TCP-пакета внутри исходящего потока данных, существующего в рамках текущего логического соединения.
В момент установления логического соединения каждый из двух партнеров генерирует свой начальный "номер в последовательности", основное требование к которому — не повторяться в промежутке времени, в течение которого TCP-пакет может находиться в сети (по сути, это время жизни IP-сегмента). Партнеры обмениваются этими начальными номерами и подтверждают их получение. Во время отправления TCP-пакетов с данными поле "номер в последовательности" содержит сумму начального номера и количества байт ранее переданных данных.
Номер подтверждения (acknowledgement number)
32-битовое поле, содержимое которого определяет (косвенно) количество принятых данных из входящего потока к TCP-модулю, формирующему TCP-пакет.
четырехбитовое поле, содержащее длину заголовка TCP-пакета в 32-битовых словах и используемое для определения начала расположения данных в TCP-пакете.
бит, установленное в 1 значение которого означает, что TCP-пакет содержит важные (urgent) данные. Подробно о данных этого типа сказано в "Важные данные".
бит, установленное в 1 значение которого означает, что TCP-пакет содержит в поле "номер подтверждения" верные данные.
бит, установленное в 1 значение которого означает, что данные содержащиеся в TCP-пакете должны быть немедленно переданы прикладной программе, для которой они адресованы. Подтверждение для TCP-пакета, содержащего единичное значение во флаге PSH, означает, что и все предыдущие TCP-пакеты достигли адресата.
бит, установливаемый в 1 в TCP-пакете, отправляемом в ответ на получение неверного TCP-пакета. Также может означать запрос на переустановление логического соединения.
бит, установленное в 1 значение которого означает, что TCP-пакет представляет собой запрос на установление логического соединения. Получение пакета с установленым флагом SYN должно быть подтверждено принимающей стороной.
бит, установленное в 1 значение которого означает, что TCP-пакет представляет собой запрос на закрытие логического соединения и является признаком конца потока данных, передаваемых в этом направлении. Получение пакета с установленым флагом FIN должно быть подтверждено принимающей стороной.
16-битовое поле, содержащее количество байт информации, которое может принять в свои внутренние буфера TCP-модуль, отправляющий партнеру данный TCP-пакет. Данное поле используется принимающим поток данных TCP-модулем для управления интенсивностью этого потока: так, установив значение поля в 0, можно полностью остановить передачу данных, которая будет возобновлена только, когда размер окна примет достаточно большое значение. Максимальный размер окна зависит от реализации, в некоторых реализациях максимальный размер может устанавливаться системным администратором (типичное значение максимального размера окна — 4096 байт). Определение оптимального размера окна — одна из наиболее сложных задач реализации протокола TCP (см. "Исключение малых окон").
16-битовое поле, содержащее Internet-контрольную сумму, подсчитанную для TCP-заголовка, данных пакета и псевдозаголовка. Псевдозаголовок включает в себя ряд полей IP-заголовка и имеет показанную на рис. 4.2 структуру.
16-битовое поле, содержащее указатель (в виде смещения) на первый байт в теле TCP-пакета, начинающий последовательность важных (urgent) данных. Данные этого типа и механизм их обработки описаны в "Важные данные".
Дополнительные данные заголовка
последовательность полей произвольной длины, описывающих необязательные данные заголовка. Протокол TCP определяет только три типа дополнительных данных заголовка:
- конец списка полей дополнительных данных;
- пусто (No Operation);
- максимальный размер пакета.
Дополнительные данные последнего типа посылаются в TCP-заголовке в момент установления логического соединения для выражения готовности TCP-модулем принимать пакеты длиннее 536 байтов. В UNIX-реализациях длина пакета обычно определяется максимальной длиной IP-сегмента для сети.
4.2. Номер порта
Номера портов играют роль адресов транспортного уровня, идентифицируя на конкретных узлах сети, по сути дела, потребителей транспортных услуг, предоставляемых как протоколом TCP, так и протоколом UDP. При этом протоколы TCP и UDP имеют свои собственные адресные пространства: например, порт номер 513 для TCP не идентичен порту номер 513 для UDP.
Примечание. Своя собственная адресация на транспортном уровне стека протоколов сетевого взаимодействия необходима для обеспечения возможности функционирования на узле сети одновременно многих сетевых приложений. Наличие в TCP-заголовке номера порта позволяет TCP-модулю, получающему последовательности TCP-пакетов, формировать раздельные потоки данных к прикладным программам.
Взаимодействие прикладных программ, использующих транспортные услуги протокола TCP (или UDP), строится согласно модели "клиент-сервер" , которая подразумевает, что одна программа (сервер) всегда пассивно ожидает обращения к ней другой программы (клиента). Связь программы-клиента и сервера идентифицируется пятеркой:
- используемый транспортный протокол (TCP или UDP);
- IP-адрес сервера;
- номер порта сервера;
- IP-адрес клиента;
- номер порта клиента.
Для того, чтобы клиент мог обращаться к необходимому ему серверу, он должен знать номер порта, по которому сервер ожидает обращения к нему ("слушает сеть"). Для прикладных программ, получивших наибольшее распространение в сетях на основе TCP/IP, номера портов фиксированы и носят название "хорошо известных номеров портов" (well-known port numbers). В UNIX-системах такие номера портов содержатся в файле /etc/services. Ниже приводятся примеры хорошо известных номеров портов для некоторых серверов (служб).
Примечание. Обратите внимание, что некоторые серверы (такие, например, как для службы portmap с номером порта 111) могут работать как по протоколу TCP, так и по протоколу UDP.
Программы-клиенты, являющиеся активной стороной во взаимодействии "клиент-сервер", могут использовать, как правило, произвольные номера портов, назначаемые динамически непосредственно перед обращением к серверу (как любые свободные на данном узле).
Примечание. Любая прикладная программа (будь то клиент или сервер) может открывать для взаимодействия любое количество портов для использования любых транспортных протоколов.
Средства разработки сетевых приложений на базе транспортных протоколов TCP и UDP описаны в "Сетевое программирование".
4.3. Принцип "скользящего окна"
Протоколы транспортного уровня, обеспечивающие надежную передачу данных, предполагают обязательное подтверждение принимающей стороной правильности полученных данных.
В "простых" протоколах сторона, отправляющая данные, отсылает пакет с данными принимающей стороне и переходит в состояние ожидания подтверждения получения правильных данных. Только после приема подтверждения становится возможной следующая посылка. Очевидно, что такой подход использует пропускную способность сети неэффективно.
В протоколе TCP используется более совершенный принцип "скользящего окна" (sliding window) , который заключается в том, что каждая сторона может отправлять партнеру максимум столько байт, сколько партнер указал в поле "размер окна" заголовка TCP-пакета, подтверждающего получение предыдущих данных.
Принцип "скользящего окна" обеспечивает "опережающую" посылку данных с "отложенным" их подтверждением. Следует отметить недостаток этого механизма: если в течение некоторого времени не будет получено "отсроченное" подтверждение ранее отправленного пакета, то отправляющий TCP-модуль будет вынужден повторить посылку всех TCP-пакетов, начиная с неподтвержденного.
Размер окна, как правило, определяется объемом свободного места в буферах принимающего TCP-модуля.
4.4. Важные данные
Протокол TCP предусматривает возможность информирования принимающей стороны взаимодействия отправляющей стороной о наличии в TCP-пакете важных данных ( urgent data ), требующих особого внимания согласно логике прикладной задачи.
Примечание. Отличие важных данных от данных основного потока заключается в том, что принимающая сторона должна, как правило, обработать их прежде ранее полученных, но еще не обработанных данных потока.
Для индикации наличия в TCP-пакете важных данных используется флаг URG TCP-заголовка, местоположение важных данных в теле TCP-пакета определяется полем "Указатель" TCP-заголовка — оно задает смещение (в стиле языка программирования C) первого байта важных данных в теле TCP-пакета. Рис. 4.3 иллюстрирует расположение важных данных в теле TCP-пакета.
Примечание. Протокол TCP предусматривает передачу важных (urgent) данных в рамках общего потока данных ("in-band"). Существуют протоколы (например, ISO), поддерживающие режим передачи важных (expedited) данных вне общего потока данных ("out-band"), что в общем случае быстрее.
4.5. Этапы TCP-взаимодействия
Взаимодействие партнеров с использованием протокола TCP строится в три этапа:
- установление логического соединения;
- обмен данными;
- закрытие соединения.
Ниже с помощью трех рисунков дается описание каждого из этапов. Рисунки иллюстрируют последовательность обмена TCP-пакетами двумя TCP-модулями: A и B. TCP-пакеты представлены тремя полями TCP-заголовка ("Номер в последовательности", "Номер подтверждения", "Флаги") и числом, характеризующим длину данных, составляющих тело TCP-пакета (заметим, что реально поля длины данных в TCP-заголовке нет). Стрелками показаны направления пересылки пакетов.
Рис. 4.4 иллюстрирует этап установления соединения, реализуемый как "трехшаговое рукопожатие" (three-way handshake). На первом шаге TCP-модуль A, играя роль клиента, посылает TCP-модулю B пакет с установленным флагом SYN и начальным значением номера в последовательности равным 1000. TCP-модуль B, будучи готов со своей стороны установить соединение, отвечает TCP-пакетом, подтверждающим правильный прием запроса (поле "Номер подтверждения" на 1 больше начального номера в последовательности для TCP-модуля A и среди флагов есть установленный в 1 флаг ACK) и информирующим о готовности установить соединение (взведен флаг SYN и установлен в 5000 начальный номер в последовательности). На третьем шаге TCP-модуль A подтверждает правильность приема TCP-пакета от B.
Примечание. Некоторые протоколы транспортного уровня (но не TCP) допускают обмен данными уже на этапе установления логического соединения.
Рис. 4.5 иллюстрирует этап двустороннего обмена данными между TCP-модулями A и B. TCP-модуль, принимающий адресованные ему данные, всегда подтверждает их прием, вычисляя значение поля "Номер подтверждения" в заголовке ответного TCP-пакета как сумму пришедшего "Номера в последовательности" и длины правильно принятых данных. Отметим, что посылка данных к партнеру и подтверждение принятых от него данных реализуются в рамках одного TCP-пакета.
Рис. 4.6 иллюстрирует закрытие соединения по инициативе TCP-модуля A, посылающего партнеру TCP-пакет с установленным флагом FIN. Прием запроса на закрытие соединения TCP-модуль B подтверждает пакетом, содержащем в своем заголовке поле "Номер подтверждения", значение которого (1052) на 1 больше значения принятого "Номера в последовательности" (1051). После этого посылка каких-либо данных TCP-модулем A становится невозможной, однако модуль B имеет данные для передачи, которые он отправляет TCP-модулю A и получает подтверждение на их прием. Затем TCP-модуль B формирует пакет с флагом FIN, после подтверждения его приема соединение считается закрытым.
Примечание. Обратите внимание на то обстоятельство, что при подтверждении TCP-пакетов, содержащих единичные флаги SYN или FIN, значение поля "Номер подтверждения" на 1 больше значения соответствующего поля "Номер в последовательности", несмотря на то, что никакие данные в подтверждаемых TCP-пакетах не передаются.
Примечание. Рассмотренный пример не включает в себя ситуации, связанные с "потерей" TCP-пакетов в сети, и их обработку, связанную с повторной передачей данных.
4.6. Таймеры
4.6.1. Таймер повторной передачи
Данный таймер взводится значением RTO ( Retransmission TimeOut — интервал до повторной передачи) в момент посылки TCP-пакета адресату. Если таймер окажется сброшенным в ноль до момента получения подтверждения пакета, то этот пакет должен быть послан вновь.
Ясно, что величина RTO не может быть фиксированной, т.к. TCP-пакеты до разных адресатов следуют по различным маршрутам через сети, скорость передачи данных в которых может различаться более чем в тысячи раз. Для вычисления "оптимального" значения RTO в каждом логическом соединении используется специальная процедура, специфицированная в RFC 793.
Согласно этой процедуре, для каждого TCP-пакета измеряется величина RTT ( Round Trip Time — интервал времени от момента посылки TCP-пакета до момента получения подтверждения на него). На основе измеренных RTT вычисляется величина SRTT ( Smoothed RTT — сглаженный RTT) по следующей формуле:
где k — сглаживающий коэффициент (например, 0.9).
Примечание. Приведенная формула обеспечивает фильтрацию нетипичных (пиковых) значений измеренной величины RTT.
"Оптимальное" значение RTO вычисляется по формуле:
U — ограничение сверху на значение RTO (например, 30 секунд);
L — ограничение снизу на значение RTO (например, 1 секунда);
p — коэффициент "запаса" (например, 2).
Если после повторной посылки TCP-пакета, опять не будет получено его подтверждение за интервал времени RTO, то попытки послать TCP-пакеты будут повторены (до 12 раз), но каждый раз с экспоненциально возрастающим значением RTO. Только после неудачи всей серии повторных посылок связь между партнерами будет считаться аварийно закрытой.
4.6.2. Таймер возобновления передачи
В ходе взаимодействия двух TCP-модулей ( A и B ) вполне возможна следующая ситуация:
- TCP-модуль B уведомляет TCP-модуль A о невозможности приема от него данных, определяя размер окна равным 0;
- TCP-модуль A, имея данные для передачи, переходит в состояние ожидания от TCP-модуля B пакета с ненулевым размером окна;
- TCP-модуль B, у которого освободилось некоторое пространство в буферах, посылает модулю A TCP-пакет с ненулевым размером окна;
- адресованный модулю A пакет "теряется" по какой-либо причине и оба TCP-модуля переходят в состояние бесконечного ожидания.
Средством выхода из такого тупикового состояния и служит таймер возобновления передачи ( persistence timer — "настойчивый" таймер). Он взводится в момент получения TCP-пакета с нулевым значением поля "Размер окна" в его заголовке (типичное начальное значение для этого таймера — 5 секунд). Если до момента обнуления таймера не будет получено разрешение на возобновление передачи данных, то ожидающий разрешения TCP-модуль отправляет партнеру пакет, содержащий всего лишь 1 байт данных. По реакции партнера, возвращающего пакет с нулевым/ненулевым значением размера окна, TCP-модуль продолжает ожидание или возобновляет посылку данных.
4.6.3. Таймер закрытия связи
Протокол TCP предусматривает следующий простой прием предотвращения появления в сети TCP-пакетов, не имеющих адресатов: после закрытия логического соединения между партнерами номера портов, использовавшихся в этом соединении, остаются еще некоторый интервал времени действительными, что дает возможность долго блуждавшим по сети TCP-пакетам добраться до места назначения (где они будут просто проигнорированы). Величина этого интервала равна удвоенному времени жизни IP-сегмента (обычно, 2*15=30 секунд).
Примечание. Пользователи ОС UNIX могут почувствовать эффект от использования этого приема, попытавшись перезапустить некоторую прикладную программу, использующую TCP, сразу же после ее завершения.
4.6.4. Таймеры поддержки соединения
Ниже описывается механизм, используемый для проверки ненарушенности логического соединения между TCP-модулями.
Каждый TCP-модуль, участвующий в логическом соединении, через фиксированный промежуток времени ( keep-alive timer ), равный обычно 45 секундам, периодически отправляет партнеру пустые (не содержащие данных) TCP-пакеты и ждет их подтверждения. Каждое полученное подтверждение говорит о ненарушенности соединения. Если же в течении определенного интервала времени ( idle timer ), равного обычно 360 секудам, не будет получено ни одного подтверждения, то логическое соединение считается оборванным.
Примечание. Очевидно, что данный механизм имеет смысл включать в работу только тогда, когда партнеры по TCP-взаимодействию приостановили по какой-либо причине обмен данных на достаточно длительный срок (более 45 секунд).
Примечание. Стандартная спецификация протокола TCP не включает в себя описанный механизм, однако он реализован во всех UNIX-системах.
4.7. Алгоритмы повышения эффективности
Ниже описываются некоторые алгоритмы, используемые для повышения эффективности взаимодействия по протоколу TCP в UNIX-реализациях и не являющиеся частью спецификации TCP.
4.7.1. Задержка подтверждения
Задержка отсылки подтверждения принятого пакета используется для сокращения числа TCP-пакетов, которыми обмениваются партнеры по взаимодействию. Поясним эффект от такой задержки следующим примером.
Пусть клиентская часть некоторого приложения (например, службы telnet) направляет серверной части некоторые данные (в случае telnet — строку символов, представляющих команду OC UNIX, которая должна быть выполнена на удаленном узле сети). Серверная часть, получив данные и обработав их, должна вернуть клиенту результат (в случае с telnet — это стандартный вывод исполненной команды).
В ситуации без задержки TCP-модуль на стороне сервера, приняв пакет с данными и разместив их в своем буфере, сразу же отвечает подтверждающим пакетом, содержащим в своем заголовке и некоторый (уменьшенный) размер окна для приема последующих данных. Спустя некоторое (обычно, очень короткое) время данные из буфера передаются серверной части прикладной программы. Освобождение места в буфере заставляет TCP-модуль отправлять партнеру на стороне клиента TCP-пакет с новым (увеличившимся) размером окна. Тем временем прикладная программа, обработав полученные данные (часто за небольшое время), передает результат TCP-модулю для отсылки его клиенту, для чего модуль формирует еще один пакет. Итого: одна транзакция потребовала от TCP-модуля на стороне сервера посылки трех TCP-пакетов.
Введение же задержки при отсылке подтверждающего TCP-пакета позволяет в ряде случаев уменьшить количество пакетов с трех до одного, содержащего сразу подтверждение, новый размер окна и результирующие данные. Экспериментальные исследования показали, что во многих случаях "оптимальным" значением задержки является 0.2 секунды.
Для того, чтобы введение задержки сказывалось минимальным образом на приложения, предъявляющие жесткие требования к пропускной способности сети, задержка устанавливается нулевой при условии, что размер окна изменяется более чем на 35% или (в абсолютном исчислении) на удвоенный максимальный размер TCP-пакета.
4.7.2. Исключение малых окон
Возможны ситуации, когда прикладная программа, использующая TCP-сервис, "выбирает" из буфера обслуживающего ее TCP-модуля пришедшие для нее данные малыми порциями. Это приводит к генерации TCP-модулем большого количества TCP-пакетов, содержащих в своих заголовках малую величину размера окна, что в свою очередь приводит к генерации на передающей данные стороне многих TCP-пакетов с "короткими" данными. Как результат — "засорение" сети короткими пакетами и снижение ее пропускной способности.
Во избежание деградации сети вследствие описанного явления используется следующий прием: TCP-пакет, информирующий посылающую данные сторону об увеличении размера окна, формируется только при выполнении одного из двух условий:
- свободное место в буфере принимающего данные TCP-модуля увеличилось по крайней мере на четверть размера этого буфера;
- свободное место увеличилось по крайней мере на максимальный размер TCP-пакета.
Кроме того TCP-модуль, отправляющий данные, должен делать это большими порциями.
4.7.3. Исключение коротких TCP-пакетов
"Засорение" сети короткими TCP-пакетами возможно и в ситуации, когда прикладная программа, отправляющая данные партнеру по взаимодействию, делает это короткими порциями (типичный пример — любая программа, использующая графическую систему X Window System).
Для борьбы с этим используется следующий прием:
- самая первая порция данных отправляется TCP-модулем сразу же при поступлении "коротким" TCP-пакетом;
- все последующие накапливаются в буфере TCP-модуля, пока их общий объем не составит максимального размера TCP-пакета или не будет получено подтверждение предеыдущей посылки.
Однако этот подход может сказаться на быстродействии некоторых приложений, чтобы избежать этого прикладной программе предоставляются средства для принудительного "выталкивания" буферизованных данных в необходимых случаях. Кроме того, существует возможность отключения описанного механизма.
4.7.4. Алгоритм медленного старта
Опыт эксплуатации сетей на основе TCP/IP показал, что с повышением загрузки сети (особенно, сети со шлюзом) ее пропускная способность падает (хотя, казалось бы, она должна оставаться постоянной). Исследования показали, что падение обусловлено появлением в сети большого числа TCP-пакетов, повторно посылаемых к активно используемому узлу сети (обычно это шлюз в другие сети). Дело в том, что приемный буфер TCP-модуля на шлюзе очень быстро заполняется, и TCP-модуль вынужден сбрасывать поступающие к нему пакеты.
Для предупреждения подобной ситуации необходимо согласование темпа передачи TCP-пакетов с возможностями их приема на узле-адресате. Задачу согласования решает алгоритм медленного старта, постепенно повышающий темп передачи данных от медленного до "оптимального", при котором нет повторных передач TCP-пакетов. Алгоритм использует так называемое " окно перегруженности " ( congestion window ), используемое на передающей стороне для определения максимального объема передаваемых данных вместо размера, получаемого от принимающей стороны в поле окна подтверждающего пакета.
Размер "окна перегруженности" определяется на передающей стороне путем постепенного его увеличения до момента появления повторных передач (ясно, что размер этого окна никогда не превышает размера окна на принимающей стороне). Однажды определенный размер "окна перегруженности" остается неизменным, пока вновь не появятся повторные передачи, однако периодически делаются осторожные попытки и увеличить этот размер.
Эксперименты показали, что данный алгоритм позволяет уменьшить количество повторно передаваемых TCP-пакетов на 50% и повысить пропускную способность сети на 30%.
5. Протокол дэйтаграмм пользователя UDP
Протокол дэйтаграмм пользователя UDP (User Datagram Protocol) является протоколом транспортного уровня и базируется на возможностях, предоставляемых межсетевым протоколом IP. Основная задача TCP — обеспечение "быстрой" передачи данных в сети. Его транспортный адрес в заголовке IP-сегмента равен 17. Описание протокола UDP дано в RFC 768.
Его основные характеристики перечислены ниже:
- реализует взаимодействие в режиме без установлением логического (виртуального) соединения;
- организует поблочный (дэйтаграммный, пакетный) тип передачи данных;
- для идентификации партнеров по взаимодействию на транспортном уровне использует 16-битовые "номера портов";
- не гарантирует надежной передачи данных (возможна как потеря UDP-пакетов, так и их дублирование);
- не имеет средств уведомления источника UDP-пакета о правильности/ошибочности в его приеме адресатом;
- не обеспечивает правильный порядок доставки UDP-пакетов от источника к приемнику;
- может гарантировать целостность данных в UDP-пакете за счет использования контрольной суммы;
- очень прост (особенно, по сравнению с протоколом TCP).
Следует отметить, что, по сути дела, протокол транспортного уровня UDP играет роль интерфейса для прикладных программ к средствам протокола межсетевого уровня IP.
На рис. 5.1 приведен формат заголовка UDP-пакета.
Порт источника и порт приемника
16-битовые поля, содержащие номера портов, соответственно, источника и адресата UDP-пакета. Понятие "номер порта" обсуждается в "Протокол управления передачей TCP".
16-битовое поле, содержащее длину (в байтах) всего UDP-пакета, включая заголовок и данные.
16-битовое поле, содержащее Internet-контрольную сумму, подсчитанную для UDP-заголовка, данных пакета и псевдозаголовка. Псевдозаголовок (такой же, как для подсчета контрольной суммы в TCP-заголовке) включает в себя ряд полей IP-заголовка и имеет показанную на рис. 5.2 структуру.
Если поле "Контрольная сумма" UDP-заголовка содержит нулевое значение, это означает, что источник UDP-пакета контрольную сумму не подсчитывал, и приемник выполнять ее проверку не должен. Некоторые реализации протокола UDP (например, в SunOS — клоне ОС UNIX от Sun Microsystems) контрольную сумму не подсчитывают в принципе, полагаясь на возможности контроля целостности данных, реализованные в протоколах сетевого уровня (например, в Ethernet).
6. Межсетевой протокол управляющих сообщений ICMP
Межсетевой протокол управляющих сообщений ICMP (Internet Control Message Protocol), специфицированный в RFC 792, играет роль транспортного протокола для управляющей и диагностической информации, которой обмениваются между собой IP-, TCP- или UDP-модули скрытно от приложений. Протокол ICMP поддерживается в обязательном порядке ка ждым IP-модулем. Его транспортный адрес в IP-заголовке равен 1.
6.1. Заголовок ICMP-пакета
Поскольку протокол ICMP используется для транспортировки весьма различной информации, то фиксируется лишь общая структура заголовка ICMP-пакета, имеющего формат, показанный на рис. 6.1.
однобайтовое поле, содержащее идентификатор типа ICMP-пакета. Возможные значения этого поля приведены в таблице.
однобайтовое поле, значение которого конкретизирует назначение ICMP-пакета определенного типа.
16-битовое поле, содержащее Internet-контрольную сумму, подсчитанную для всего ICMP-пакета целиком.
четырезбайтовое поле, предназначенное для хранения разнообразной информации, специфичной для ICMP-пакетов определенного типа (например, номера в TCP-последовательности, IP-адреса и т.п.).
Здесь содержится заголовок IP-сегмента, явившегося порождения данного ICMP-пакета, и первые 8 байт данных тела этого IP-сегмента. Если ICMP-пакет есть результат проявления аномалии в TCP- или UDP-взаимодействии, то эти 8 байт будут представлять собой первые восемь байтов, соответственно, TCP- или UDP-заголовка, что дает возможность определить, в частности, номера портов (а, следовательно, и использующие их прикладные программы).
Для ICMP-пакетов некоторых типов это может содержать не начало IP-сегмента, а тестовые данные.
Источниками и обработчиками ICMP-пакетов могуть быть как IP-модули, так и TCP- и UDP-модули (но никогда прикладные программы).
Проблемы в доставке и обработке ICMP-пакетов никогда не приводят к порождению новых ICMP-пакетов, уведомляющих об этих проблемах. Сделано это с целью избежать возможных бесконечных циклов генерации ICMP-пакетов в сети.
6.2. Типы ICMP-пакетов
Здесь рассматриваются 6 типов ICMP-пакетов, реализованных во всех клонах и версиях ОС UNIX.
6.2.1. Адресат недоступен
ICMP-пакет этого типа генерируется в следующих случаях:
- сеть, узел сети, протокол или порт являются недоступными;
- в ходе продвижения по сети IP-сегмента потребовалась его фрагментация, однако в заголовке сегмента установлен флаг DF, запрещающий делать это;
- предписываемый маршрут, указанный в поле дополнительных данных IP-сегмента, оказался недействительным (несуществующим или неактивным).
6.2.2. Подавление источника
В ситуациях, когда некоторый узел (как правило, шлюз) не имеет достаточно места в своих буферах для размещения интенсивно поступающих к нему данных, он может послать узлам-источникам ICMP-пакет данного типа ( source quench ). Узел-источник в ответ на такое уведомление обязан уменьшить темп передачи данных.
В ранних UNIX-реализациях протоколов TCP/IP ICMP-пакеты этого типа игнорировались. В TCP-реализациях, поддерживающих алгоритм медленного старта, в ответ на это сообщение уменьшается размер "окна перегруженности". UDP-модули игнорируют это сообщение, информируя при этом обслуживаемую прикладную программу о требовании приемника уменьшить интенсивность и/или размер дэйтаграмм.
6.2.3. Перенаправление
ICMP-пакет этого типа посылается источнику данных, когда узел-шлюз обнаруживает, что источник может направлять свои данные непосредственно к следующему шлюзу маршрута. Такой ICMP-пакет содержит в себе IP-адрес этого шлюза. Этот IP-адрес должен быть включен в таблицу маршрутизации на узле-источнике данных.
6.2.4. Эхо
Для реализации эха IP-модуль на узле A отправляет узлу B ICMP-пакет типа "запрос эха", содержащий в своем теле вместо IP-заголовка тестовые данные произвольной длины. Узел B, получив такой запрос, возвращает узлу A ICMP-пакет типа "ответ на запрос эха", содержащий те же данные, что и в запросе. Эхо-посылки используются для проверки достижимости удаленных узлов сети и измерения времени прохождения данных.
6.2.5. Исчерпано время жизни
ICMP-пакет данного типа посылается источнику IP-сегмента, который должен быть сброшен по одной из двух причин:
1) исчерпано время жизни IP-сегмента;
2) исчерпано допустимое время на сборку фрагментированного IP-сегмента.
6.2.6. Неверный параметр
С помощью ICMP-пакета данного типа источник IP-сегмента информируется о том, что данный сегмент сброшен вследствие наличия ошибки в каком-либо из полей его заголовка.
7. Протоколы сетевого уровня
Ниже кратко описывается реализвция стека протоколов TCP/IP на базе ряда протоколов сетевого уровня.
7.1. Ethernet
Протокол Ethernet был разработан в начале 1970-х годов совместно фирмами Xerox, DEC и Intel. На его базе в 1982 г. был принят международный стандарт IEEE 802.3 .
Использование протокола сетевого уровня Ethernet совместно с протоколами TCP/IP регламентируется RFC 894.
Основными характеристиками протокола Ethernet являются следующие:
- шинная логическая топология сети;
- скорость передачи данных 10 мегабит в секунду;
- используется для построения локальных вычислительных сетей;
- обмен данными между узлами сети осуществляется кадрами;
- для разделения шины между многими узлами используется механизм CSMA/CD;
- обеспечивает широковещательную (broadcast) и многопунктовую (multicast) рассылку данных.
В качестве физической среды передачи данных Ethernet использует:
- "толстый" коаксиальный кабель (так называемый 10base5 Ethernet);
- "тонкий" коаксиальный кабель (10base2);
- оптоволоконный кабель;
- витая пара (10baseT).
В первых трех случаях физическая топология сети реально является шинной, в последнем — физическая топология сети представляет собой "звезду".
Примечание. Существуют современные версии Ethernet, обеспечивающие скорость передачи в 100 мегабит в секунду.
Примечание. Ethernet позволяет объединить в локальную сеть узлы, расположенные друг от друга на расстоянии от нескольких десятков метров (10baseT) до нескольких километров (сегменты 10base5, связанные повторителями).
Механизм CSMA/CD (Carrier Sense Multiple Acces with Collision Detection — Множественный Доступ с Контролем Носителя и Обнаружением Столкновений) подразумевает следующий алгоритм получения узлом сети доступа к шине:
- прослушивание шины (sense carrier) на предмет наличия в ней сигналов передачи данных другими узлами;
- если шина занята, то отложить передачу, если свободна — начать передачу данных;
- в течение первых 47 микросекунд передачи кадра данных вести проверку столкновений (collisions) в шине, связанных с возможным одновременным началом передачи данных и другими узлами сети;
- при обнаружении столкновения прекратить передачу данных и перейти в состояние ожидания на период времени случайной длины, а потом возобновить попытки передачи кадра.
Обмен данными по протоколу Ethernet всегда реализуется программно-аппаратно с помощью двух компонентов:
- сетевого контроллера (чаще всего имеющего вид печатной платы, вставляемой в корпус ЭВМ), подключаемого к шине (коаксиальному кабелю, оптоволокну или витой паре медных проводов);
- драйвера сетевого контроллера, обеспечивающего интерфейс сетевого программного обеспечения (например, IP-модуля) с контроллером.
Примечание. В ОС UNIX сетевой контроллер и его драйвер принято называть " сетевым интерфейсом ".
7.1.1. Формат кадра данных Ethernet
На рис. 7.1 представлен формат кадра данных протокола Ethernet. Для иллюстративных целей показана вложенность в кадр IP-сегмента (содержащего, в свою очередь, TCP-пакет).
64-битовое поле, содержащее фиксированную последовательность битов, используемую для синхронизации схем приема сигналов на узле-адресате.
Адрес приемника и адрес источника
48-битовые поля, содержащие Ethernet-адреса принимающего и передающего кадр узлов сети.
Каждый Ethernet-контроллер в мире имеет уникальный 6-байтовый адрес. Ethernet-адрес принято записывать в виде последовательности шести разделенных символом "двоеточие" двузначных шестнадцатиричных чисел, где каждое число представляет собой значение одного байта адреса, напрмер, f1:e2:d3:c4:b5:a6.
Примечание. Как правило, Ethernet-адрес жестко "зашит" в контроллере, однако существуют контроллеры, допускающие его изменение программным путем.
16-битовое поле, содержащее идентификатор протокола вышележащего уровня, использующего данный Ethernet-кадр. Т.е. поле определяет принадлежность содержимого тела кадра. Наличие данного поля в кадре обеспечивает возможность функционирования в одной сети на базе Ethernet одновременного нескольких различных стеков протоколов, а не только одного TCP/IP.
Примерами значений данного поля являются следующие:
- 0x0800 — протокол IP;
- 0x0806 — протокол ARP.
содержит данные, передаваемые в кадре протоколом вышележащего уровня (на рисунке это IP-сегмент, тело которого используется для пересылки TCP-пакета).
Максимальная длина тела кадра протокола сетевого уровня обозначается как MTU (Maximum Transmission Unit) и для Ethernet составляет 1500 байтов.
32-битовое поле, содержащее CRC-контрольную сумму, подсчитанную для всего кадра.
Минимальная длина Ethernet-кадра составляет 64 байта (512 бит). Такое ограничение связано с тем, что контроль столкновений различных кадров в Ethernet-шине согласно алгоритму CSMA/CD выполняется на интервале времени в 47 микросекунд. За это время осуществляется передача 470 бит (при скорости 10 мегабит в секунду), так что 512 — это округление 470 до числа, являющегося степенью 2.
В ситуациях, когда длина данных, передаваемых в теле кадра, недостаточна для формирования кадра длиной не менее 64 байтов, драйвер Ethernet-контроллера искусственно дополняет тело пакета до необходимой длины.
Примечание. Интересно, что согласно стандарту IEEE 802.3 рассмотренное выше 16-битовое поле типа кадра на самом деле является полем длины (в байтах) тела Ethernet-кадра. Для идентификации типа содержимого тела кадра предлагается использовать специальный протокол LLC (Logic Link Control — протокол управления логической связью), занимающий промежуточное положение между Ethernet и вышележащими протоколами. Однако протокол LLC в среде UNIX (а, значит, и в большинстве других ОС) реализован не был: стандартом "de facto" остаются спецификации RFC 894. Хотя надо отметить, что выбор значений идентификаторов типа кадра (0x0800 и больше) не исключает возможности использования этого поля одновременно и для идентификации типа, и для хранения длины тела кадра (максимум 1500).
7.1.2. Протоколы трансляции адресов
Ethernet подобно другим протоколам сетевого уровня обладает собственной системой адресации узлов сети, отличной от системы адресации, принятой в TCP/IP. Это приводит к необходимости взаимной трансляции адресов "IP-адрес в Ethernet-адрес" и обратно.
В UNIX-системах такая трансляция выполняется с помощью специальной таблицы соответствий пар адресов различного типа, которая динамически создается и обновляется сетевым интерфейсом. В момент активизации сетевого интерфейса содержимое таблицы трансляции может загружаться из созданного вручную специального административного файла, однако это не является обязательным.
Для поддержания таблицы трансляции в актуальном состоянии, отражающем текущий состав узлов Ethernet-сети, используется протокол ARP (Address Resolution Protocol) , описанный в RFC 826.
Структура ARP-сегмента приведена на рис. 7.2.
Поле "Hardware" содержит идентификатор типа адреса на сетевом уровне (в нашем случае — Ethernet).
Поле "Идентификатор протокола" определяет протокол межсетевого уровня (в нашем случае — IP).
Поля длин задают длину адресов ( в нашем случае: "Длина HW-адреса" равна 6, а "Длина адреса" равна 4).
Поле "Операция" содержит идентификатор типа ARP-сегмента (запрос или ответ).
Примечание. Как видно из структуры ARP-сегмента протокол ARP может быть использован для совместной работы TCP/IP не только с протоколом Ethernet, но и с другими протоколами сетевого уровня, когда в этом есть необходимость.
Алгоритм использования протокола ARP для построения таблицы трансляции на некотором узле сети (назовем его А) выглядит следующим образом.
- На узле А IP-модуль передает сетевому интерфейсу сегмент для его пересылки узлу Б (в сегменте присутствует IP-адрес узла Б). Сетевой интерфейс просматривает свою таблицу трансляции адресов, пытаясь по известному IP-адресу узла Б определить его Ethernet-адрес. Если необходимая строка в таблице есть, то сетевой интерфейс формирует Ethernet-кадр и передает его в сеть.
- Если нужной строки в таблице нет, то сетевой интерфейс строит ARP-сегмент, содержащий IP-адрес узла Б, упаковывает его в Ethernet-кадр. Этот кадр в качестве Ethernet-адреса приемника содержит широковещательный адрес, что обеспечит получение этого кадра всеми узлами локальной сети.
- Все узлы локальной сети получают данный Ethernet-кадр, а в нем ARP-сегмент. IP-адрес из ARP-сегмента сравнивается с собственным IP-адресом и, если они совпадают (это должно иметь место только на узле Б), то собственный Ethernet-адрес возвращается узлу А в ответном ARP-сегменте.
- Получив ответный ARP-сегмент, сетевой интерфейс на узле А добавляет в таблицу трансляции новую строку, содержимое которой и будет использовано для посылки IP-сегмента к узлу Б.
Для того, чтобы таблица трансляции адресов с малым временем реакции отслеживала изменения в сети, ее строки периодически (через 1. 20 минут) принудительно очищаются.
Примечание. Очевидно, что использование протокола ARP возможно только для сетей, обеспечивающих широковещательную рассылку данных.
Задачу построения строк таблицы трансляции по известному Ethernet-адресу решает протокол RARP (Reverse ARP), описанный в RFC 903 и использующий сегмент той же структуры, что протокол ARP. Определение IP-адреса по известному Ethernet-адресу требуется в момент начальной загрузки бездисковых ЭВМ, подключенных к сети.
Примечание. Использование протоколов ARP и RARP может быть отключено системным администратором.
7.2. Протокол SLIP
Протокол SLIP (Serial Line Internet Protocol) обеспечивает соединение двух ЭВМ через последовательный интерфейс (например, V.24 ). Протокол SLIP описан в RFC 1055.
Протокол очень прост. Все SLIP-кадры начинаются со служебного символа 0xEB, называемого ESC, а заканчиваются служебным символом 0xC0, называемым END. Между этими символами располагаются передаваемые данные.
Если служебные символы встречаются в передаваемых данных, то они отсылаются приемнику в виде двухбайтовых последовательностей:
RFC 1055 не специфицирует максимальной длины кадра (MTU), но существующие реализации протокола ориентированы на значение MTU равное 1006 байт.
Примечание. Очевидно, что скорость передачи данных по последовательному интерфейсу невелика. Для повышения эффективности протокола SLIP в RFC 1144 была предложена его модификация, учитывающая то обстоятельство, что при TCP-взаимодействии по последовательной линии большинство полей IP- и TCP-заголовков остаются неизменными на все время логического соединения. Данная модификация SLIP реально пересылает в своих кадрах только те поля IP- и TCP-заголовков, которые меняют свое значение от кадра к кадру.
7.3. Протокол PPP
Протокол PPP (Point-to-Point Protocol) также может быть использован для соединения двух ЭВМ по последовательному интерфейсу. Протокол PPP (RFC 1331) разработан позднее протокола SLIP, поэтому в нем ликвидированы некоторые недостатки протокола SLIP, в частности:
- поддерживаются различные протоколы вышележащего уровня (а не только IP);
- используются контрольные суммы.
Для идентификации границ PPP-кадра используется служебный символ 0x7E.
Передаче данных по протоколу PPP предшествует этап тестирования и конфигурирования соединения с помощью протокола LCP (Link Control Protocol), являющегося частью PPP. LCP используется и для завершения соединения.
Кроме того, для обмена управляющей информацией используется протокол NCP (Network Control Protocol). Каждый протокол, лежащий выше PPP, имеет свою версию протокола NCP. NCP, определенный для протокола IP, носит название IPCP (Internet Protocol Control Protocol).
Теория:Протоколы:TCP
TCP (transmission control protocol — протокол управления передачей) — один из основных протоколов передачи данных интернета, предназначенный для управления передачей данных. Сети и подсети, в которых совместно используются протоколы TCP и IP называются сетями TCP/IP.
В стеке протоколов IP TCP выполняет функции протокола транспортного уровня модели OSI.
Механизм TCP предоставляет поток данных с предварительной установкой соединения, осуществляет повторный запрос данных в случае потери данных и устраняет дублирование при получении двух копий одного пакета, гарантируя тем самым, в отличие от UDP, целостность передаваемых данных и уведомление отправителя о результатах передачи.
Реализации TCP обычно встроены в ядра ОС. Существуют реализации TCP, работающие в пространстве пользователя.
Когда осуществляется передача от компьютера к компьютеру через Интернет, TCP работает на верхнем уровне между двумя конечными системами, например, браузером и веб-сервером. TCP осуществляет надежную передачу потока байтов от одной программы на некотором компьютере к другой программе на другом компьютере (например, программы для электронной почты, для обмена файлами). TCP контролирует длину сообщения, скорость обмена сообщениями, сетевой трафик.
Содержание
Заголовок сегмента TCP
| Бит | 0 — 3 | 4 — 9 | 10 — 15 | 16 — 31 | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | Порт источника | Порт назначения | ||||||||||||||||||||||||||||||
| 32 | Порядковый номер | |||||||||||||||||||||||||||||||
| 64 | Номер подтверждения | |||||||||||||||||||||||||||||||
| 96 | Длина заголовка | Зарезервировано | Флаги | Размер Окна | ||||||||||||||||||||||||||||
| 128 | Контрольная сумма | Указатель важности | ||||||||||||||||||||||||||||||
| 160 | Опции (необязательное, но используется практически всегда) | |||||||||||||||||||||||||||||||
| 160/192+ | Данные | |||||||||||||||||||||||||||||||
Порт источника, Порт назначения
Эти 16-битные поля содержат номера портов — числа, которые определяются по специальному списку.
Порт источника идентифицирует приложение клиента, с которого отправлены пакеты. Ответные данные передаются клиенту на основании этого номера.
Порт назначения идентифицирует порт, на который отправлен пакет.
Порядковый номер
Порядковый номер выполняет две задачи:
- Если установлен флаг SYN, то это изначальный порядковый номер — ISN (Initial Sequence Number), и первый байт данных, которые будут переданы в следующем пакете, будет иметь номер, равный ISN + 1.
- В противном случае, если SYN не установлен, первый байт данных, передаваемый в данном пакете, имеет этот порядковый номер
Поскольку поток TCP в общем случае может быть длиннее, чем число различных состояний этого поля, то все операции с порядковым номером должны выполняться по модулю 2 32 . Это накладывает практическое ограничение на использование TCP. Если скорость передачи коммуникационной системы такова, чтобы в течение MSL (максимального времени жизни сегмента) произошло переполнение порядкового номера, то в сети может появиться два сегмента с одинаковым номером, относящихся к разным частям потока, и приёмник получит некорректные данные.
Номер подтверждения
Если установлен флаг ACK, то это поле содержит порядковый номер, ожидаемый получателем в следующий раз. Помечает этот сегмент как подтверждение получения.
Длина заголовка (смещение данных)
Это поле определяет размер заголовка пакета TCP в 4-байтных (4-октетных) словах. Минимальный размер составляет 5 слов, а максимальный — 15, что составляет 20 и 60 байт соответственно. Смещение считается от начала заголовка TCP.
Зарезервировано
Зарезервировано (6 бит) для будущего использования и должно устанавливаться в ноль. Из них два (5-й и 6-й) уже определены:
- CWR (Congestion Window Reduced) — Поле «Окно перегрузки уменьшено» — флаг установлен отправителем, чтобы указать, что получен пакет с установленным флагом ECE (RFC 3168)
- ECE (ECN-Echo) — Поле «Эхо ECN» — указывает, что данный узел способен на ECN (явное уведомление перегрузки) и для указания отправителю о перегрузках в сети (RFC 3168)
Флаги (управляющие биты)
Это поле содержит 6 битовых флагов:
- URG — поле «Указатель важности» задействовано (Urgent pointer field is significant)
- ACK — поле «Номер подтверждения» задействовано (Acknowledgement field is significant)
- PSH — (Push function) инструктирует получателя протолкнуть данные, накопившиеся в приёмном буфере, в приложение пользователя
- RST — оборвать соединения, сбросить буфер (очистка буфера) (Reset the connection)
- SYN — синхронизация номеров последовательности (Synchronize sequence numbers)
- FIN (final, бит) — флаг, будучи установлен, указывает на завершение соединения (FIN bit used for connection termination).
Размер окна
В этом поле содержится число, определяющее в байтах размер данных, которые отправитель может отправить без получения подтверждения.
Контрольная сумма
Поле контрольной суммы — это 16-битное дополнение к сумме всех 16-битных слов заголовка(включая псевдозаголовок) и данных. Если сегмент, по которому вычисляется контрольная сумма, имеет длину не кратную 16-ти битам, то длина сегмента увеличивается до кратной 16-ти, за счет дополнения к нему справа нулевых битов заполнения. Биты заполнения (0) не передаются в сообщении и служат только для расчёта контрольной суммы. При расчёте контрольной суммы значение самого поля контрольной суммы принимается равным 0.
Указатель важности
16-битовое значение положительного смещения от порядкового номера в данном сегменте. Это поле указывает порядковый номер октета, которым заканчиваются важные (urgent) данные. Поле принимается во внимание только для пакетов с установленным флагом URG.
Опции
Могут применяться в некоторых случаях для расширения протокола. Иногда используются для тестирования. На данный момент в опции практически всегда включают 2 байта NOP (в данном случае 0x01) и 10 байт, задающих timestamps. Вычислить длину поля опции можно через значение поля смещения.
Механизм действия протокола
В отличие от традиционной альтернативы — UDP, который может сразу же начать передачу пакетов, TCP устанавливает соединения, которые должны быть созданы перед передачей данных. TCP соединение можно разделить на 3 стадии:
- Установка соединения
- Передача данных
- Завершение соединения
Состояния сеанса TCP

| Состояния сеанса TCP | |
|---|---|
| CLOSED | Начальное состояние узла. Фактически фиктивное |
| LISTEN | Сервер ожидает запросов установления соединения от клиента |
| SYN-SENT | Клиент отправил запрос серверу на установление соединения и ожидает ответа |
| SYN-RECEIVED | Сервер получил запрос на соединение, отправил ответный запрос и ожидает подтверждения |
| ESTABLISHED | Соединение установлено, идёт передача данных |
| FIN-WAIT-1 | Одна из сторон (назовём её узел-1) завершает соединение, отправив сегмент с флагом FIN |
| CLOSE-WAIT | Другая сторона (узел-2) переходит в это состояние, отправив, в свою очередь сегмент ACK и продолжает одностороннюю передачу |
| FIN-WAIT-2 | Узел-1 получает ACK, продолжает чтение и ждёт получения сегмента с флагом FIN |
| LAST-ACK | Узел-2 заканчивает передачу и отправляет сегмент с флагом FIN |
| TIME-WAIT | Узел-1 получил сегмент с флагом FIN, отправил сегмент с флагом ACK и ждёт 2*MSL секунд, перед окончательным закрытием соединения |
| CLOSING | Обе стороны инициировали закрытие соединения одновременно: после отправки сегмента с флагом FIN узел-1 также получает сегмент FIN, отправляет ACK и находится в ожидании сегмента ACK (подтверждения на свой запрос о разъединении) |
Установка соединения
Процесс начала сеанса TCP (также называемый «рукопожатие» (handshake)), состоит из трёх шагов.
1. Клиент, который намеревается установить соединение, посылает серверу сегмент с номером последовательности и флагом SYN.
- Сервер получает сегмент, запоминает номер последовательности и пытается создать сокет (буферы и управляющие структуры памяти) для обслуживания нового клиента.
- В случае успеха сервер посылает клиенту сегмент с номером последовательности и флагами SYN и ACK, и переходит в состояние SYN-RECEIVED.
- В случае неудачи сервер посылает клиенту сегмент с флагом RST.
2. Если клиент получает сегмент с флагом SYN, то он запоминает номер последовательности и посылает сегмент с флагом ACK.
- Если он одновременно получает и флаг ACK (что обычно и происходит), то он переходит в состояние ESTABLISHED.
- Если клиент получает сегмент с флагом RST, то он прекращает попытки соединиться.
- Если клиент не получает ответа в течение 10 секунд, то он повторяет процесс соединения заново.
3. Если сервер в состоянии SYN-RECEIVED получает сегмент с флагом ACK, то он переходит в состояние ESTABLISHED.
- В противном случае после тайм-аута он закрывает сокет и переходит в состояние CLOSED.
Процесс называется «трёхэтапным согласованием» (three way handshake), так как несмотря на то что возможен процесс установления соединения с использованием четырёх сегментов (SYN в сторону сервера, ACK в сторону клиента, SYN в сторону клиента, ACK в сторону сервера), на практике для экономии времени используется три сегмента.
Пример базового 3-этапного согласования:
В строке 2 TCP A начинает передачу сегмента SYN, говорящего об использовании номеров последовательности, начиная со 100. В строке 3 TCP B передает SYN и подтверждение для принятого SYN в адрес TCP A. Надо отметить, что поле подтверждения показывает ожидание TCP B приёма номера последовательности 101, подтверждающего SYN с номером 100.
В строке 4 TCP A отвечает пустым сегментом с подтверждением ACK для сегмента SYN от TCP B; в строке 5 TCP B передает некоторые данные. Отметим, что номер подтверждения сегмента в строке 5 (ACK=101) совпадает с номером последовательности в строке 4 (SEQ=101), поскольку ACK не занимает пространства номеров последовательности (если это сделать, придется подтверждать подтверждения — ACK для ACK).
Существуют экспериментальные расширения протокола TCP, сокращающие количество пакетов при установлении соединения, например TCP Fast Open. Ранее также существовало расширение T/TCP. Для прозрачного шифрования данных предлагается использовать расширение tcpcrypt.
Передача данных
При обмене данными приёмник использует номер последовательности, содержащийся в получаемых сегментах, для восстановления их исходного порядка. Приёмник уведомляет передающую сторону о номере последовательности, до которой он успешно получил данные, включая его в поле «номер подтверждения». Все получаемые данные, относящиеся к промежутку подтвержденных последовательностей, игнорируются. Если полученный сегмент содержит номер последовательности больший, чем ожидаемый, то данные из сегмента буферизируются, но номер подтвержденной последовательности не изменяется. Если впоследствии будет принят сегмент, относящийся к ожидаемому номеру последовательности, то порядок данных будет автоматически восстановлен исходя из номеров последовательностей в сегментах.
Для того, чтобы передающая сторона не отправляла данные интенсивнее, чем их может обработать приёмник, TCP содержит средства управления потоком. Для этого используется поле «окно». В сегментах, направляемых от приёмника передающей стороне, в поле «окно» указывается текущий размер приёмного буфера. Передающая сторона сохраняет размер окна и отправляет данных не более, чем указал приёмник. Если приёмник указал нулевой размер окна, то передача данных в направлении этого узла не происходит, пока приёмник не сообщит о большем размере окна.
В некоторых случаях передающее приложение может явно затребовать протолкнуть данные до некоторой последовательности принимающему приложению, не буферизируя их. Для этого используется флаг PSH. Если в полученном сегменте обнаруживается флаг PSH, то реализация TCP отдает все буферизированные на текущий момент данные принимающему приложению. «Проталкивание» используется, например, в интерактивных приложениях. В сетевых терминалах нет смысла ожидать ввода пользователя после того, как он закончил набирать команду. Поэтому последний сегмент, содержащий команду, обязан содержать флаг PSH, чтобы приложение на принимающей стороне смогло начать её выполнение.
Завершение соединения
Завершение соединения можно рассмотреть в три этапа:
- Посылка серверу от клиента флага FIN на завершение соединения.
- Сервер посылает клиенту флаги ответа ACK , FIN, что соединение закрыто.
- После получения этих флагов клиент закрывает соединение и в подтверждение отправляет серверу ACK , что соединение закрыто.
Известные проблемы
Максимальный размер сегмента
TCP требует явного указания максимального размера сегмента (MSS) в случае, если виртуальное соединение осуществляется через сегмент сети, где максимальный размер блока (MTU) менее, чем стандартный MTU Ethernet (1500 байт).
В протоколах туннелирования, таких как GRE, IPIP, а также PPPoE MTU туннель меньше, чем стандартный, поэтому сегмент TCP максимального размера имеет длину пакета больше, чем MTU. Это приводит к фрагментации и уменьшению скорости передачи полезных данных. Если на каком-либо узле фрагментация запрещена, то со стороны пользователя это выглядит как «зависание» соединений. При этом «зависание» может происходить в произвольные моменты времени, а именно тогда, когда отправитель использовал сегменты длиннее допустимого размера. Для решения этой проблемы на маршрутизаторах применяются правила Firewall-а, добавляющие параметр MSS во все пакеты, инициирующие соединения, чтобы отправитель использовал сегменты допустимого размера.
MSS может также управляться параметрами операционной системы.
Обнаружение ошибок при передаче данных
Хотя протокол осуществляет проверку контрольной суммы по каждому сегменту, используемый алгоритм считается слабым. Так, в 2008 году ошибка в передаче одного бита, не обнаруженная сетевыми средствами, привела к остановке серверов системы Amazon Web Services.
В общем случае распределенным сетевым приложениям рекомендуется использовать дополнительные программные средства для гарантирования целостности передаваемой информации.
Атаки на протокол
Недостатки протокола проявляются в успешных теоретических и практических атаках, при которых злоумышленник может получить доступ к передаваемым данным, выдать себя за другую сторону или привести систему в нерабочее состояние.
Реализация
Псевдозаголовок
TCP-заголовок не содержит информации об адресе отправителя и получателя, поэтому даже при совпадении порта получателя нельзя с точностью сказать, что сообщение пришло в нужное место. Поскольку назначением протокола TCP является надёжная доставка сообщений, то этот момент имеет принципиальное значение. Эту задачу можно было решить разными способами. Самый очевидный — добавить информацию об адресе назначения в заголовок TCP, однако это, во-первых, приводит к дублированию информации, что снижает долю полезной информации переносимой TCP-сегментом, а во-вторых, нарушает принцип инкапсуляции модели OSI. Поэтому разработчики протокола пошли другим путём и использовали дополнительный псевдозаголовок:
TCP-псевдозаголовок IPv4
Биты 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 0-31 IP-адрес отправителя (Source address) 32-63 IP-адрес получателя (Destination address) 64-95 0 0 0 0 0 0 0 0 Протокол (Protocol) Длина TCP-сегмента (TCP length) TCP-псевдозаголовок IPv6
- Протокол (Protocol)/Протокол верхнего уровня (Next header) — содержит в себе значение 6 (00000110 в двоичном виде, 0x6 — в шестнадцатеричном) — идентификатор TCP-протокола.
- Длина TCP-сегмента (TCP length) — содержит в себе длину TCP-сегмента в байтах (TCP-заголовок + данные; длина псевдозаголовка не учитывается).
Псевдозаголовок не включается в TCP-сегмент. Он используется для расчета контрольной суммы перед отправлением сообщения и при его получении (получатель составляет свой псевдозаголовок, используя адрес хоста, с которого пришло сообщение, и собственный адрес, а затем считает контрольную сумму).
Освобождение от расчёта контрольной суммы
Многие реализации стека TCP/IP предоставляют возможности использования аппаратной поддержки для автоматического расчёта контрольной суммы в сетевом адаптере до передачи в сеть или после приёма из сети для верификации. Это может освобождать операционную систему от использования ценных тактов процессора при вычислении контрольной суммы.
Эта функция может приводить к тому, что анализаторы трафика, перехватывающие исходящие пакеты до их передачи в сетевой адаптер и не знающие о делегировании расчёта контрольной суммы сетевому адаптеру, могут сообщать об ошибке контрольной суммы в исходящих пакетах.