Transmission Control Protocol
TCP | |
---|---|
Название | Transmission Control Protocol |
Уровень (по модели OSI) | Транспортный |
Семейство | TCP/IP |
Спецификация | RFC 793 (сентябрь 1981 года) / STD 7 |
Основные реализации | UNIX, Linux, BSD, Windows |
Расширяемость | Опции |
Transmission Control Protocol (TCP, протокол управления передачей) — один из основных протоколов передачи данных интернета, предназначенный для управления передачей данных.
В стеке протоколов TCP/IP выполняет функции транспортного уровня модели OSI.
Механизм TCP предоставляет поток данных с предварительной установкой соединения, осуществляет повторный запрос данных в случае потери данных и устраняет дублирование при получении двух копий одного пакета, гарантируя тем самым, в отличие от UDP, целостность передаваемых данных и уведомление отправителя о результатах передачи.
Реализации TCP обычно встроены в ядра ОС. Существуют реализации TCP, работающие в пространстве пользователя.
Когда осуществляется передача от компьютера к компьютеру через Интернет, TCP работает на верхнем уровне между двумя конечными системами, например, браузером и веб-сервером. TCP осуществляет надёжную передачу потока байтов от одного процесса к другому. TCP реализует управление потоком, управление перегрузкой, рукопожатие, надежную передачу.
Содержание
1 Заголовок сегмента TCP
1.1 Порт источника, Порт назначения
1.2 Порядковый номер
1.3 Номер подтверждения
1.4 Длина заголовка (смещение данных)
1.5 Зарезервировано
1.6 Флаги (управляющие биты)
1.7 Размер окна
1.8 Контрольная сумма
1.9 Указатель важности
1.10 Опции
2 Механизм действия протокола
2.1 Состояния сеанса TCP
2.2 Установка соединения
2.3 Передача данных
2.4 Завершение соединения
3 Известные проблемы
3.1 Максимальный размер сегмента
3.2 Обнаружение ошибок при передаче данных
3.3 Атаки на протокол
4 Реализация
4.1 Псевдозаголовок
4.2 Освобождение от расчёта контрольной суммы
5 См. также
6 Ссылки
7 Литература
Заголовок сегмента TCP |
Бит | 0 — 3 | 4 — 9 | 10 — 15 | 16 — 31 | ||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | Порт источника, Source Port | Порт назначения, Destination Port | ||||||||||||||||||||||||||||||
32 | Порядковый номер, Sequence Number (SN) | |||||||||||||||||||||||||||||||
64 | Номер подтверждения, Acknowledgment Number (ACK SN) | |||||||||||||||||||||||||||||||
96 | Длина заголовка | Зарезервировано | Флаги | Размер Окна | ||||||||||||||||||||||||||||
128 | Контрольная сумма | Указатель важности | ||||||||||||||||||||||||||||||
160 | Опции (необязательное, но используется практически всегда) | |||||||||||||||||||||||||||||||
160/192+ | Данные |
Порт источника, Порт назначения |
Эти 16-битные поля содержат номера портов — числа, которые определяются по специальному списку.
Порт источника идентифицирует приложение клиента, с которого отправлены пакеты. Ответные данные передаются клиенту на основании этого номера.
Порт назначения идентифицирует порт, на который отправлен пакет.
Порядковый номер |
Порядковый номер выполняет две задачи:
- Если установлен флаг SYN, то это изначальный порядковый номер — ISN (Initial Sequence Number), и первый байт данных, которые будут переданы в следующем пакете, будет иметь номер, равный ISN + 1.
- В противном случае, если SYN не установлен, первый байт данных, передаваемый в данном пакете, имеет этот порядковый номер
Поскольку поток TCP в общем случае может быть длиннее, чем число различных состояний этого поля, то все операции с порядковым номером должны выполняться по модулю 232. Это накладывает практическое ограничение на использование TCP. Если скорость передачи коммуникационной системы такова, чтобы в течение MSL (максимального времени жизни сегмента) произошло переполнение порядкового номера, то в сети может появиться два сегмента с одинаковым номером, относящихся к разным частям потока, и приёмник получит некорректные данные.
Номер подтверждения |
Acknowledgment Number (ACK SN) (32 бита) — если установлен флаг ACK, то это поле содержит порядковый номер октета, который отправитель данного сегмента желает получить. Это означает, что все предыдущие октеты (с номерами от ISN+1 до ACK-1 включительно) были успешно получены.
Длина заголовка (смещение данных) |
Длина заголовка (Data offset) занимает 4 бита и указывает значение длины заголовка, измеренное в 32-битовых словах. Минимальный размер составляет 20 байт (пять 32-битовых слов), а максимальный — 60 байт (пятнадцать 32-битовых слов). Длина заголовка определяет смещение полезных данных относительно начала сегмента. Например, Data offset равное 1111 говорит о том, что заголовок занимает пятнадцать 32-битных слова (15 строк*32 бита в каждой строке/8 бит = 60 байт).
Зарезервировано |
Зарезервировано (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-этапного согласования:
TCP A TCP B
1. CLOSED LISTEN
2. SYN-SENT --> <SEQ=100><CTL=SYN> --> SYN-RECEIVED
3. ESTABLISHED <-- <SEQ=300><ACK=101><CTL=SYN,ACK> <-- SYN-RECEIVED
4. ESTABLISHED --> <SEQ=101><ACK=301><CTL=ACK> --> ESTABLISHED
5. ESTABLISHED <-- <SEQ=301><ACK=101><CTL=ACK> <-- ESTABLISHED
В строке 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[en]. Ранее также существовало расширение 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 может также управляться параметрами операционной системы.
Обнаружение ошибок при передаче данных |
Хотя протокол осуществляет проверку контрольной суммы по каждому сегменту, используемый алгоритм считается слабым [1]. Так, в 2008 году ошибка в передаче одного бита, не обнаруженная сетевыми средствами, привела к остановке серверов системы Amazon Web Services [2].
В общем случае распределенным сетевым приложениям рекомендуется использовать дополнительные программные средства для гарантирования целостности передаваемой информации[3].
Атаки на протокол |
Недостатки протокола проявляются в успешных теоретических и практических атаках, при которых злоумышленник может получить доступ к передаваемым данным, выдать себя за другую сторону или привести систему в нерабочее состояние.
Реализация |
Псевдозаголовок |
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
Биты | 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-95 | IP-адрес отправителя (Source address) | |||||||||||||||||||||||||||||||
128-223 | IP-адрес получателя (Destination address) | |||||||||||||||||||||||||||||||
224-255 | Длина TCP-сегмента (TCP length) | |||||||||||||||||||||||||||||||
256-287 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | Протокол верхнего уровня (Next header) |
- Протокол (Protocol)/Протокол верхнего уровня (Next header) — содержит в себе значение 6 (00000110 в двоичном виде, 0x6 — в шестнадцатеричном) — идентификатор TCP-протокола.
- Длина TCP-сегмента (TCP length) — содержит в себе длину TCP-сегмента в байтах (TCP-заголовок + данные; длина псевдозаголовка не учитывается).
Псевдозаголовок не включается в TCP-сегмент. Он используется для расчета контрольной суммы перед отправлением сообщения и при его получении (получатель составляет свой псевдозаголовок, используя адрес хоста, с которого пришло сообщение, и собственный адрес, а затем считает контрольную сумму).
Освобождение от расчёта контрольной суммы |
Многие реализации стека TCP/IP предоставляют возможности использования аппаратной поддержки для автоматического расчёта контрольной суммы в сетевом адаптере до передачи в сеть или после приёма из сети для верификации. Это может освобождать операционную систему от использования ценных тактов процессора при вычислении контрольной суммы.
Эта функция может приводить к тому, что анализаторы трафика, перехватывающие исходящие пакеты до их передачи в сетевой адаптер и не знающие о делегировании расчёта контрольной суммы сетевому адаптеру, могут сообщать об ошибке контрольной суммы в исходящих пакетах.
См. также |
- SCTP
- TCP hijacking
- BIC TCP
- Порт (TCP/IP)
- IP
- UDP
Ссылки |
RFC 793 (англ.) — Transmission Control Protocol- RFC 793 на русском
- Спецификация протокола TCP
Литература |
- Терри Оглтри. Модернизация и ремонт сетей = Upgrading and Repairing Networks. — 4-е изд. — М.: «Вильямс», 2005. — С. 1328. — ISBN 0-7897-2817-6.
- Дуглас Камер. Сети TCP/IP, том 1. Принципы, протоколы и структура = Internetworking with TCP/IP, Vol. 1: Principles, Protocols and Architecture. — М.: «Вильямс», 2003. — С. 880. — ISBN 0-13-018380-6.
- Андрей Робачевский, Сергей Немнюгин, Ольга Стесик. Операционная система UNIX. — 2-е изд. — "БХВ-Петербург", 2007. — С. 656. — ISBN 5-94157-538-6.
Для улучшения этой статьи желательно: |