RFC 9293 Transmission Control Protocol (TCP)

image_print
Internet Engineering Task Force (IETF)                      W. Eddy, Ed.
STD: 7                                                       MTI Systems
Request for Comments: 9293                                   August 2022
Obsoletes: 793, 879, 2873, 6093, 6429, 6528,                            
           6691                                                         
Updates: 1011, 1122, 5961                                               
Category: Standards Track                                               
ISSN: 2070-1721

Transmission Control Protocol (TCP)

Протокол управления передачей (TCP)

PDF

Аннотация

Этот документ задаёт протокол управления передачей (Transmission Control Protocol или TCP). TCP является важным протоколом транспортного уровня в стеке протоколов Internet и непрерывно развивался в течение десятилетий использования и роста сети Internet. За это время было внесено много изменений в протокол TCP, заданный RFC 793, хотя они были документированы лишь частично. В этом документе такие изменения собраны и объединены со спецификацией RFC 793. Документ отменяет RFC 793, а также RFC 879, RFC 2873, RFC 6093, RFC 6429, RFC 6528 и RFC 6691, которые частично обновляли RFC 793. Документ обновляет RFC 1011 и RFC 1122 и его следует считать заменой тем частям указанных документов, которые относятся к требованиям TCP. Документ также обновляет RFC 5961, добавляя небольшое разъяснение в обработку сброса в состоянии SYN-RECEIVED. Биты управления в заголовке TCP из RFC 793 также обновлены на основе RFC 3168.

Статус документа

Документ относится к категории Internet Standards Track.

Документ является результатом работы IETF1 и представляет согласованный взгляд сообщества IETF. Документ прошёл открытое обсуждение и был одобрен для публикации IESG2. Дополнительную информацию о стандартах Internet можно найти в разделе 2 в RFC 7841.

Информация о текущем статусе документа, найденных ошибках и способах обратной связи доступна по ссылке https://www.rfc-editor.org/info/rfc9293.

Авторские права

Copyright (c) 2022. Авторские права принадлежат IETF Trust и лицам, указанным в качестве авторов документа. Все права защищены.

К документу применимы права и ограничения, указанные в BCP 78 и IETF Trust Legal Provisions и относящиеся к документам IETF (http://trustee.ietf.org/license-info), на момент публикации данного документа. Прочтите упомянутые документы внимательно. Фрагменты программного кода, включённые в этот документ, распространяются в соответствии с упрощённой лицензией BSD, как указано в параграфе 4.e документа IETF Trust Legal Provisions, без каких-либо гарантий (как указано в Simplified BSD License).

Документ может содержать материалы из IETF Document или IETF Contribution, опубликованных или публично доступных до 10 ноября 2008 года. Лица, контролирующие авторские права на некоторые из таких документов, могли не предоставить IETF Trust права разрешать внесение изменений в такие документы за рамками процессов IETF Standards. Без получения соответствующего разрешения от лиц, контролирующих авторские права этот документ не может быть изменён вне рамок процесса IETF Standards, не могут также создаваться производные документы за рамками процесса IETF Standards за исключением форматирования документа для публикации или перевода с английского языка на другие языки.

Оглавление

Исключено в варианте HTML.

1. Назначение и область действия

В 1981 году был выпущен документ RFC 793 [16], описывающий протокол TCP и отменяющий опубликованные ранее спецификации TCP. С тех порт TCP получил широкое распространение и применяется в качестве транспортного протокола во множестве приложений Internet.

В течение нескольких десятилетий RFC 793 и ряд других документов служили основной спецификацией для TCP [49]. За это время в RFC 793 был обнаружен ряд ошибок, а также были обнаружены и устранены недостатки в защите, производительности и других аспектах. Со временем число документов с изменениями значительно выросло, но они никогда не объединялись в комплексное обновление базовой спецификации. Цель этого документа состоит в объединении всех изменений IETF Standards Track и других разъяснений к базовой функциональной спецификации TCP (RFC 793) в одну обновлённую версию спецификации.

В некоторых сопутствующих документах упоминаются важные алгоритмы, применяемые в TCP (например, для контроля перегрузки), но они не включены полностью в этот документ. Это осознанный выбор, поскольку базовая спецификация может применяться со множеством дополнительных алгоритмов, разрабатываемых и включаемых независимо. Этот документ фокусируется на общей для всех реализаций TCP основе, которая должна поддерживаться для совместимости взаимодействия. Поскольку некоторые дополнительные свойства TCP сами по себе достаточно сложны (например, усовершенствованное восстановление потерь и контроль перегрузок), они могут быть объединены независимо в будущих сопутствующих документах.

В дополнение к спецификации протокола, описывающей формат сегмента TCP, правила генерации и обработки, реализуемые в кода, RFC 793 и его обновления содержат сведения и описания, помогающие понять различные аспекты устройства и работы протокола. Данный документ не пытается изменить или обновить эти сведения и сосредоточен лишь на обновлении нормативной спецификации протокола. В документе сохранены ссылки на источники с важными разъяснениями и обоснованиями, где это уместно.

Этот документ предназначен как для проверки имеющихся реализаций TCP, так и для создания новых.

2. Введение

В RFC 793 рассмотрены цели проектирования TCP и даны примеры работы, включая организацию и завершение соединений, повтор передачи пакетов и восстановление потерь.

Этот документ описывает базовую функциональность, ожидаемую от современных реализаций TCP, и заменяет спецификацию протокола в RFC 793. Здесь не повторяются и не обновляются введение и концепции из разделов 1 и 2 в RFC 793. Даны ссылки на другие документы, содержащие разъяснения теории работы, обоснования и обсуждение проектных решений. Данные документ сосредоточен исключительно на нормативном поведении протокола.

В работе [49] представлено детальное руководство по RFC, определяющим TCP и описывающим различные важные алгоритмы. Этот документ содержит разделы, посвящённые настоятельно рекомендуемым усовершенствованиям,повышающим производительность и улучшающим другие аспекты TCP сверх описанных в этом документе базовых операций. Например, реализация контроля перегрузок (такая как [8]) является требованием TCP, но это сложная тема сама по себе и не рассматривается подробно в этом документе, поскольку имеется много вариантов и возможностей, которые не влияют на базовую совместимость. Точно так же большинство современных реализаций TCP включает высокопроизводительные расширения из [47], но они не являются обязательными и не рассматриваются в этом документе. Вопросы работы TCP по нескольким путям также рассматриваются отдельно [59].

Список отличий от RFC 793 приведён в разделе 5. Отличия от RFC 793.

2.1. Уровни требований

Ключевые слова необходимо (MUST), недопустимо (MUST NOT), требуется (REQUIRED), нужно (SHALL), не нужно (SHALL NOT), следует (SHOULD), не следует (SHOULD NOT), рекомендуется (RECOMMENDED), не рекомендуется (NOT RECOMMENDED), возможно (MAY), необязательно (OPTIONAL) в данном документе должны интерпретироваться в соответствии с BCP 14[3] [12] тогда и только тогда, когда они выделены шрифтом, как показано здесь.

Каждое применение ключевых слов RFC 2119 в документе помечено ссылкой на Приложение B. Сводка требований TCP. Предложения с ключевым словом MUST содержат метку MUST-X, где X указывает числовой идентификатор требования в Приложении B. Аналогично помечаются и требования уровней SHOULD, MAY, RECOMMENDED. Требования уровня SHOULD NOT и MUST NOT помечены как SHOULD и MUST.

2.2. Основные концепции TCP

TCP обеспечивает приложениям надёжное упорядоченное обслеживание потоков байтов. Потоки байтов приложений доставляются через сеть в сегментах TCP, каждый из которых передаётся как дейтаграмма IP (Internet Protocol).

Надёжность (гарантии доставки) TCP включает обнаружение потери пакетов (по номерам) и ошибок (по контрольным суммам сегментов), а также их исправление путём повторной передачи.

TCP поддерживает индивидуальную (unicast) доставку данных. Имеются anycast-приложения, способные применять TCP без изменений, хотя это связано с риском нестабильности при смене поведения пересылки на нижелижащих уровнях [46].

Протокол TCP ориентирован на (прямые) соединения, хотя, по сути, не включает возможность проверки их живучести.

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

TCP использует номера портов для идентификации прикладных служб и мультиплексирования разных потоков между хостами.

Более подробное описание свойств TCP по сравнению с другими транспортными протоколами представлено в параграфе 3.1 [52]. Дополнительное описание мотивов разработки TCP и роли протокола в стеке протоколов Internet можно найти в разделе Section 2 [16] и ранних версиях спецификации TCP.

3. Функциональная спецификация

3.1. Формат заголовка

Сегменты TCP передаются как дейтаграммы IP. Заголовок протокола IP содержит несколько полей, включая адреса хостов источника и получателя [1] [13]. Заголовок TCP размещается вслед за заголовками IP и содержит относящиеся к TCP сведения. Такое деление позволяет использовать на хосте протоколы, отличные от TCP. В ранних реализациях стека протоколов Internet поля заголовков IP были частью TCP.

Этот документ описывает протокол TCP, использующий заголовки TCP. Формат заголовка TCP, за которым могут следовать любые пользовательские данные, показан на рисунке 1 с использованием стиля из [66].

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          Source Port          |       Destination Port        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Sequence Number                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Acknowledgment Number                      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Data |       |C|E|U|A|P|R|S|F|                               |
| Offset| Rsrvd |W|C|R|C|S|S|Y|I|            Window             |
|       |       |R|E|G|K|H|T|N|N|                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           Checksum            |         Urgent Pointer        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           [Options]                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               :
:                             Data                              :
:                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Каждая «ячейка» на рисунке соответствует 1 биту.

Рисунок 1. Формат заголовка TCP.


Source Port – 16 битов

Номер порта у отправителя.

Destination Port – 16 битов

Номер порта у получателя.

Sequence Number – 32 бита

Порядковый номер первого октета данных в этом сегменте (за исключением случаев, когда установлен флаг SYN). При установленном флаге SYN порядковым номером является исходный порядковый номер (initial sequence number или ISN) и первый октет данных имеет номер ISN+1.

Acknowledgment Number – 32 бита

При устновленном бите ACK это поле содержит значение следующего порядкового номера, который отправитель этого сегмента оджидает получить. Когда соединение установлено, это поле передаётся всегда.

Data Offset (DOffset) – 4 бита

Число 32-битовых слов в заголовке TCP (указывает начало данных). Размер заголовка TCP (даже при наличии опций) всегда содержит целое число 32-битовых слов.

Reserved (Rsrvd) – 4 бита

Набор битов, зарезервированных на будущее. Эти биты должны сбрасываться (0) при генерации сегментов и игнорироваться при получении, если соответствующие (будущие) свойства не реализованы отправителем или получателем.

Control bits

Биты управления, называемые также флагами (flag). Назначение битов контролируется IANA через реестр TCP Header Flags [62]. В настоящее время выделены флаги CWR, ECE, URG, ACK, PSH, RST, SYN, FIN.

CWR – 1 бит

Сокрещено окно перегрузки (насыщения) [6].

ECE – 1 бит

ECN-Echo [6].

URG – 1 бит

Указатель срочности (важности) в поле Urgent Pointer имеет значение.

ACK – 1 бит

Поле Acknowledgment имеет значение.

PSH – 1 бит

Функция выталкивания (Push), см. 3.9.1.2. Send.

RST – 1 бит

Сброс соединения (Reset).

SYN – 1 бит

Синхронизация порядковых номеров.

FIN – 1 бит

У отправителя больше нет данных.

Window – 16 битов

Число октетов данных, начиная с указанного в поле Acknowledgment, которые отправитель этого сегмента готов воспринять. Значение смещается при использовании расширения для масштабирования окна [47].
Размер окна должен трактоваться как целое число без знака, иначе окна большего размера будут рассматриваться как имеющие отрицательный размер и TCP не будет работать (MUST-1). Реализациям рекомендуется резервировать 32-битовые поля для размеров окон передачи и приёма в записи соединения и выполнять все расчёты для окон с использованием 32 битов (REC-1).

Checksum – 16 битов

Поле контрольной суммы содержит 16-битовое поразрядное дополнение суммы всех 16-битовых слов в заголовке и данных. Расчёт контрольной суммы выполняется с учётом размера, кратного 16-битам. Если сегмент содержит нечётное число октетов в заголовке и данных, к нему добавляется октет нулей для выравнивания размера, который применяется лишь при расчёте контрольной суммы и не передаётся в сегменте. При расчёте контрольной суммы значение поля Checksum принимается нулевым.
Контрольная сумма учитывает также псевдозаголовок (Рисунок 2), концептуально предшествующий заголовку TCP.Этот псевдозаголовок имеет размер 96 битов для IPv4 и 320 для IPv6. Включение псевдозаголовка в контрольную сумму обеспечивает соединению TCP защиту от некорректно маршрутизированных сегментов. Эта информация содержится в заголовках IP и передаётся через интерфейс TCP-сеть в аргументах или результатах вызовов реализацией TCP функций уровня IP.
+--------+--------+--------+--------+
|           Source Address          |
+--------+--------+--------+--------+
|         Destination Address       |
+--------+--------+--------+--------+
|  zero  |  PTCL  |    TCP Length   |
+--------+--------+--------+--------+

Рисунок 2. Псевдозаголовок IPv4.

Компоненты псевдозаголовка IPv4 приведены ниже.

Source Address

Адрес источника IPv4 в сетевом порядке байтов.

Destination Address

Адрес получателя IPv4 в сетевом порядке байтов.

zero

Биты, установленные в 0.

PTCL

Номер протокола из заголовка IP.

TCP Length

Размер заголовка и данных TCP в октетах (вычисляется, а не передаётся явно) без учёта 12 октетов псевдозаголовка.
Псевдозаголовок для IPv6 определён в параграфе 8.1 RFC 8200 [13] и содержит поля IPv6 Source Address и Destination Address, Upper-Layer Packet Length (32-битовое значение, в остальном эквивалентное TCP Length в псевдозаголовке IPv4), 3 нулевых байта заполнения и значение Next Header, которое отличается от заголовка IPv6 при наличии заголовков расширения между заголовками IPv6 и TCP.
Контрольная сумма TCP обязательна. Отправитель должен создавать её (MUST-2), а получатель должен проверять (MUST-3).

Urgent Pointer – 16 битов

Это поле передаёт текущее значение указателя важности (срочности) как положительное смещение от порядкового номера в этом сегменте. Этот указатель задаёт номер октета, следующего за важными данными. Поле интерпретируется лишь для сегментов с установленным флагом URG.

Options – [TCP Option]; size(Options) == (DOffset-5)*32;

Поле опций присутствует лишь при DOffset > 5. Отметим, что приведённое выше выражение включает помещенное после опций заполнение.
Опции могут размещаться в конце заголовка TCP и занимают целое число октетов. Все опции учитываются в контрольной сумме. Опция может начинаться на любой границе октета. Имеется два варианта формата опций:
  1. однооктетная опция;
  2. октет вида опции (option-kind), октет размера опции и фактические данные (option-data) опции.
В поле размера (option-length) учитываются два октета option-kind и option-length, а также октеты option-data.
Отметим, что список опций может быть короче, нежели указывает поле Data Offset. Содержимое заголовка после опции End of Option List должно дополняться нулями (MUST-69).
Список определённых опций контролируется IANA [62] и каждая опция определена в RFC, как указано здесь. Набор включает экспериментальные опции, которые могут быть расширены для одновременной поддержки нескольких вариантов применения [45].
Реализация TCP может поддерживать любые определённые опции, но должна поддерживать опции, указанные ниже (MUST-4 – отметим, что поддержка опции Maximum Segment Size задана также MUST-14 в параграфе 3.7.1).

Таблица 1. Набор обязательных опций.

 

Тип

Размер

Назначение

0

Опция завершения опций (End of Option List).

1

Нет операции (No-Operation или NOP).

2

4

Максимальный размер сегмента (MSS).

 

Эти опции подробно описаны в параграфе 3.2. Определения конкретных опций.
Реализация TCP должна быть способна принимать опции TCP в любом сегменте (MUST-5).
Реализация TCP должна (MUST-6) игнорировать без ошибки либые опции TCP, которые она не реализует,предполагая, что опция имеет поле размера. Все опции TCP, кроме End of Option List (EOL) и No-Operation (NOP), включая все будущие опции, должны иметь поле размера (MUST-68). Реализация TCP должна быть готова обработать некорректный размер опции (например, 0), для чего рекомендуется процедура, сбрасывающая соединение и записывающая причину ошибки в системный журнал – log (MUST-7).
Отметим, что продолжаются работы по расширению пространства, доступного для опций TCP, например, [65].

Data – переменный размер

Пользовательские данные, передаваемые в сегменте TCP.

3.2. Определения конкретных опций

Набор обязательных опций TCP включает End of Option List (конец списка опций), No-Operation (нет операции) иMaximum Segment Size (максимальный размер сегмента или MSS).

Формат End of Option List Option показан ниже.

 0
 0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+
|       0       |
+-+-+-+-+-+-+-+-+


Kind – 1 байт; Kind == 0

Эта опция указывает завершение набора опций, которое может не совпадать с концом заголовка TCP в соответствии с полем Data Offset. Опция указывает завершение всех опций в заголовке, а не конкретной опции и её нужно применять лишь в тех случаях, когда конец опций не совпадает с завершением заголовка TCP.

Формат No-Operation Option показан ниже

 0
 0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+
|       1       |
+-+-+-+-+-+-+-+-+


Kind – 1 байт; Kind == 1

Эту опции можно помещать между любыми опциями, например, для выравнивания следующей опции по границе слова. Нет гарантии использования этой опции отправителем, поэтому получатели должны быть готовы к обработке опций, не начинающихся на границе слова (MUST-64).

Формат опции Maximum Segment Size Option показан ниже.

 0 1 2 3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|       2       |     Length    |   Maximum Segment Size (MSS)  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+


Kind – 1 байт; Kind == 2

При наличии этой опции она указывает максимальный размер сегмента, который готова воспринимать передавшая опцию сторона TCP. Значение опции ограничено пределом размера сборки фрагментов IP. Поле может передаваться в начальном запросе соединения (т. е. в сегменте с флагом SYN) и его недопустимо включать в другие сегменты (MUST-65). Если опция не используется, разрешён любой размер сегментов. Более полное описание опции дано в параграфе 3.7.1. Максимальный размер сегмента (MSS).

Length – 1 байт; Length == 4

Lразмер опции в байтах.

Maximum Segment Size (MSS) – 2 байта

Макимальный размер сегмента, который готова принимать передавшая опцию сторона TCP.

3.2.1. Другие опции общего назначения

В других RFC определены некоторые опции общего назначения, которые рекомендуется реализовать для повышения производительности, но они не требуются с точки зрения базовой совместимости TCP. Это опции селективных подтверждений (Selective Acknowledgment или SACK) [22] [26], временных меток (Timestamp или TS) [47], масштабирования окна (Window Scale или WS) [47].

3.2.2. Экспериментальные опции TCP

Экспериментальные опции TCP заданы в [30], а в [45] описано рекомендуемое применение этих опций.

3.3. Обзор терминологии TCP

В этом параграфе приведён обзор основных терминов, требуемых для понимания деталей работы протокола в оставшейся части документа. Глоссарий терминов приведён в разделе 4. Глоссарий.

3.3.1. Основные переменные состояния соединений

Перед обсуждением деталей работы реализации TCP введём некоторые термины и обозначения. Для поддержки соединения TCP нужно поддерживать состояния некоторых переменных. Предполагается, что эти переменные храняться в записи соединения, называемой блоком управления передачей (Transmission Control Block или TCB). В TCB хранятся локальные и удалённые адреса IP и номера портов, уровень защиты IP, назначение (compartment) соединения (см. Приложение A.1), указательи на пользовательские буферы приёма и передачи, указатели на очередь повтора передачи и текущий сегмент, а также некоторые переменные для порядковых номеров приёма и передачи.

Таблица 2. Переменные последовательности Send.

 

Переменная

Описание

SND.UNA

Передача не подтверждена

SND.NXT

Передать следующим

SND.WND

Окно передачи

SND.UP

Указатель важности для передачи

SND.WL1

Порядковый номер сегмента, использованный для последнего обновления окна

SND.WL2

Номер сегмента подтверждения, использованный для последнего обновления окна

ISS

Исходный порядковый номер для передачи

 

Таблица 3. Переменные последовательности Receive.

 

Переменная

Описание

RCV.NXT

Принять следующим

RCV.WND

Окно приема

RCV.UP

Указатель важности для приема

IRS

Исходный порядковый номер для приема

 

Приведённые ниже рисунки помогут связать некоторые из этих переменных с пространством номеров.

     1         2          3          4
----------|----------|----------|----------
       SND.UNA    SND.NXT    SND.UNA
                            +SND.WND

1 - старые порядковые номера, которые были подтверждены
2 - порядковые номера неподтвержденных данных
3 - порядковые номера, разрешённые для новой передачи данных
4 - будущие порядковые номера, которые ещё не разрешены

Рисунок 3. Пространство номеров передачи.


Окно передачи является частью пространства номеров, помеченной 3 на рисунке 3.

Окно приёма является частью пространства номеров, помеченной 2 на рисунке 4.

    1          2          3
----------|----------|----------
       RCV.NXT    RCV.NXT
                 +RCV.WND

1 - старые порядковые номера, которые были подтверждены
2 - порядковые номера, разрешённые для нового приёма данных
3 - будущие порядковые номера, которые ещё не разрешены

Рисунок 4. Пространство номеров приема.


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

Таблица 4. Переменные из текущего сегмента.

 

Переменная

Описание

SEG.SEQ

Порядковый номер сегмента

SEG.ACK

Номер подтверждения сегмента

SEG.LEN

Размер сегмента

SEG.WND

Окно сегмента

SEG.UP

Указатель важности сегмента

 

3.3.2. Обзор конечного автомата

В процессе своего существования соединение проходит через последовательность состояний LISTEN, SYN-SENT, SYN-RECEIVED, ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING, LAST-ACK, TIME-WAIT и фиктивное состояние CLOSED. Состояние CLOSED фиктивно, поскольку в нем нет TCB и, следовательно, соединения.

LISTEN

Ожидание запроса соединения от любого удалённого партнёра TCP и порта.

SYN-SENT

Ожидание соответствующего запроса соединения после отправки своего запроса.

SYN-RECEIVED

Ожидание подтверждения запроса соединения после отправки запросов обеими сторонами.

ESTABLISHED

Представляет созданное (открытое) соединение, в котором полученные данные могут быть доставлены пользователю. Это обычно состояние в фазе передачи данных через соединение.

FIN-WAIT-1

Ожидание запроса на завершение соединения от удалённого партнёра TCP или подтверждения переданного ранее запроса на завершение соединения.

FIN-WAIT-2

Ожидание запроса на завершение соединения от удалённого партнёра TCP.

CLOSE-WAIT

Ожидание запроса на завершение соединения от локального пользователя.

CLOSING

Ожидание подтверждения запроса на завершение соединения от удалённого партнёра TCP.

LAST-ACK

Ожидание подтверждения запроса на завершение соединения, переданного удалённому партнёру TCP (этот запрос уже включает подтверждение запроса на завершение соединения от удалённого партнёра TCP).

TIME-WAIT

Ожидание в течение времени, достаточного, чтобы убедиться в получении удаленным партнёром TCP подтверждения своего запроса на завершение соединения и избежать влияния задержанных сегментов прежних соединений на новые.

CLOSED

Представляет отсутствие соединения.

Соединение TCP меняет состояние по событиям, которые включают пользовательские вызовы, OPEN, SEND, RECEIVE, CLOSE, ABORT, STATUS, входящие сегменты, особенно с флагами SYN, ACK, RST, FIN и тайм-ауты.

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

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

                            +---------+ ---------\      active OPEN
                            |  CLOSED |            \    -----------
                            +---------+<---------\   \   create TCB
                              |     ^              \   \  snd SYN
                 passive OPEN |     |   CLOSE        \   \
                 ------------ |     | ----------       \   \
                  create TCB  |     | delete TCB         \   \
                              V     |                      \   \
          rcv RST (note 1)  +---------+            CLOSE    |    \
       -------------------->|  LISTEN |          ---------- |     |
      /                     +---------+          delete TCB |     |
     /           rcv SYN      |     |     SEND              |     |
    /           -----------   |     |    -------            |     V
+--------+      snd SYN,ACK  /       \   snd SYN          +--------+
|        |<-----------------           ------------------>|        |
|  SYN   |                    rcv SYN                     |  SYN   |
|  RCVD  |<-----------------------------------------------|  SENT  |
|        |                  snd SYN,ACK                   |        |
|        |------------------           -------------------|        |
+--------+   rcv ACK of SYN  \       /  rcv SYN,ACK       +--------+
   |         --------------   |     |   -----------
   |                x         |     |     snd ACK
   |                          V     V
   |  CLOSE                 +---------+
   | -------                |  ESTAB  |
   | snd FIN                +---------+
   |                 CLOSE    |     |    rcv FIN
   V                -------   |     |    -------
+---------+         snd FIN  /       \   snd ACK         +---------+
|  FIN    |<----------------          ------------------>|  CLOSE  |
| WAIT-1  |------------------                            |   WAIT  |
+---------+          rcv FIN  \                          +---------+
  | rcv ACK of FIN   -------   |                          CLOSE  |
  | --------------   snd ACK   |                         ------- |
  V        x                   V                         snd FIN V
+---------+               +---------+                    +---------+
|FINWAIT-2|               | CLOSING |                    | LAST-ACK|
+---------+               +---------+                    +---------+
  |              rcv ACK of FIN |                 rcv ACK of FIN |
  |  rcv FIN     -------------- |    Timeout=2MSL -------------- |
  |  -------            x       V    ------------        x       V
   \ snd ACK              +---------+delete TCB          +---------+
     -------------------->|TIME-WAIT|------------------->| CLOSED  |
                          +---------+                    +---------+
  1. Переход из состояния SYN-RECEIVED в LISTEN при получении RST является условным по наличию принятого SYN-RECEIVED после пассивного вызова OPEN.

  2. На рисунке опущен переход из FIN-WAIT-1 в TIME-WAIT, если получен сегмент FIN и локальный сегмент FIN подтверждён.

  3. Сегмент RST можно передать из любого состояния с соответствующим переходом в состояние TIME-WAIT (см. обоснование в [70]). Эти переходы не показаны явно, чтобы не загромождать рисунок. Точно так же не показан переход в состояние LISTEN или CLOSED при получении RST в любом состоянии.

Рисунок 5. Диаграмма состояний соединения TCP.


Важно подчеркнуть, что диаграмма показывает лишь сводку и её не следует считать полной спецификацией. Многие детали на рисунке опущены.

3.4. Порядковые номера

Фундаментальным свойством протокола является наличие порядкового номера у каждого октета данных, переданного через соединение TCP. Поскольку все октеты упорядочены, каждый из них можно подтвердить. Применяемый механизм подтверждений является кумулятивным и подтверждение порядкового номера X означает, что получены все предшествующие октеты (но не X). Этот механизм обеспечивает прямое обнаружение дубликатов при использовании повторной передачи. Схема нумерации октетов в сегменте проста – октет, следующий сразу после заголовка имеет наименьший номер, а номера следующих октетов возрастают по порядку.

Важно помнить, что пространство порядковых номеров конечно, хотя и достаточно велико – от 0 до 232 – 1. Поскольку пространство номеров конечно, все арифметические операции с порядковыми номерами должны выполняться по модулю 232. Эта арифметика целых чисел без знака сохраняет отношения порядковых номеров при переходе от номера 232 – 1 к 0. В компьютерной арифметике по модулю есть некоторые тонкости, поэтому при программировании нужно осторожно сравнивать значения. Символ =< означает «меньше или равно» (по модулю 232).

Типовые сравнения порядковых номеров, которые должна выполнять реализация TCP, включают:

  1. определение того, что подтверждение относится к порядковому номеру, который передан, но не подтверждён;

  2. определение того, что все порядковые номера из сегмента были подтверждены (например, для удаления сегмента из очереди повторной передачи);

  3. определение того, что входящий сегментсодержит ожидаемые номера (т. е. «перекрывется» с окном приема).

В ответ на передачу данных конечная точка TCP будет получать подтверждения, для обработки которых нужно выполнять перечисленные ниже сравнения.

SND.UNA = самый старый из неподтвержденных номеров.

SND.NXT = следующий номер для передачи.

SEG.ACK = подтверждение от принимающего партнёра TCP (следующий номер, ожидаемый им).

SEG.SEQ = первый порядковый номер в сегменте.

SEG.LEN = число октетов, занимаемых данными в сегменте (с учётом SYN и FIN).

SEG.SEQ+SEG.LEN-1 = последний порядковый номер в сегменте.

Новым подтверждением (его называют приемлемым – acceptable ack) является то, для которого выполняется условие

SND.UNA < SEG.ACK =< SND.NXT

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

При получении данных требуется выполнять указанные ниже сравнения.

RCV.NXT = следующий номер, ожидаемый во входящем сегменте, и является ли он левым (нижним) краем окна приёма.

RCV.NXT+RCV.WND-1 = последний номер, ожидаемый во входящем сегменте, и является ли он правым (верхним) краем окна приёма.

SEG.SEQ = первый порядковый номер во входящем сегменте.

SEG.SEQ+SEG.LEN-1 = последний порядковый номер во входящем сегменте.

Считается, что сегмент является частью допустимой последовательности приёма, если

RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND

или

RCV.NXT =< SEG.SEQ+SEG.LEN-1 < RCV.NXT+RCV.WND

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

На деле все немного сложнее и из-за нулевых окон и сегментов нулевого размера возникают 4 случая приемлемости входящего сегмента, указанные в таблице 5.

Таблица 5. Проверка пригодности сегментов.

 

Размер сегмента

Окно приема

Проверка

0
0
 SEG.SEQ = RCV.NXT
0
>0
 RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND
>0
0
 Не поддерживается
>0
>0
 RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND 
 или
 RCV.NXT =< SEG.SEQ+SEG.LEN-1 < RCV.NXT+RCV.WND

 

Отметим, что при нулевом размере окна приёма следует принимать лишь сегменты ACK. Это позволяет реализации TCP передавать данные и принимать подтверждения (ACK), установив нулевое окно приема. Получатель TCP должен обрабатывать поля RST и URG во всех входящих сегментах даже при нулевом размере окна приема (MUST-66).

Схема нумерации применяется также для защиты некоторой управляющей информации. Это достигается за счёт неявного включения некоторых флагов управления в пространство номеров, чтобы их можно было передать повторно и повторить без путаницы (т. е. действовать будет одна и только одна копия элемента управления). Управляющая информация не передаётся физически в пространстве сегмента данных, поэтому нужно принять правила для неявного назначения номеров элементам управления. Такая защита требуется лишь для флагов SYN и FIN, которые применяются только при создании и закрытии соединений. Для нумерации считается, что SYN присутствует перед первым октетом фактических данных в сегменте, тогда как FIN считается находящимся после последнего фактического элемента данных в сегменте с соответствующим флагом. Размер сегмента (SEG.LEN) учитывает как данные, так и занимающие пространство номеров элементы управления. При наличии SYN в переменной SEG.SEQ содержится порядковый номер SYN.

3.4.1. Выбор начального порядкового номера

Соединение определяется парой сокетов и может использоваться неоднократно. Новые экземпляры соединений называют инкарнациями соединения. В связи с этим возникает проблема – как реализация TCP идентифицирует дубликаты сегментов из предыдущих инкарнаций соединения? Эта проблема становится явной, когда соединение создаётся и завершается быстро или прерывается из-за потери памяти, а затем организуется снова. Для поддержки таких ситуаций состояние TIME-WAIT ограничивает темп повторного использования соединения, а описанный ниже выбор начального порядкового номера дополнительно защищает от неоднозначности принадлежности входящего пакета соединению.

Чтобы избежать путаницы, нужно предотвратить использование новой инкарнацией сегментов прежней инкарнации, которые все ещё могут присутствовать в сети и содержать те же порядковые номера. Нужно обеспечить гарантиюэтого даже в случаях, когда конечная точка TCP теряет все сведения об использованных номерах. При создании новых соединений применяется генератор исходного порядкового номера (initial sequence number или ISN), выбирающий новое 32-битовое значение ISN. Имеются проблемы безопасности, связанные с возможностью находящегося вне пути злоумышленника предсказать или угадать значение ISN [42].

Начальные порядковые номера TCP создаются из числовой последовательности, которая монотонно возрастает до достижения максимального значения (wrap), что обычно называют «часами». Эти часы представляют собой 32-битовый счётчик, который увеличивается не реже 1 раза приблизительно каждые 4 мксек, хотя не предполагается, что счётчик работает в реальном масштабе времени или точен и его не требуется сохранять при перезагрузке. Эти часы предназначены для того, чтобы гарантировать уникальность создаваемых ISN в течение максимального срока жизни сегмента (Maximum Segment Lifetime или MSL), который много меньше цикла счётчика, чоставляющего примерно 4,55 часа. Следует отметить, что в современных сетях с высокой скоростью передачи данных, где порядковые номера могут перекрываться в течение MSL, рекомендуется применять опцию Timestamp, описанную в параграфе 3.4.3.

Реализация TCP должна применять описанный выше тип «часов» для управления выбором начальных номеров (MUST-8) и следует генерировать эти номера на основе выражения

 ISN = M + F(localip, localport, remoteip, remoteport, secretkey)

где M – значение 4-микросекундного таймера, F() – псевдослучайная функция (pseudorandom function или PRF) параметров идентификации соединения (localip, localport, remoteip, remoteport) и секретного ключа (secretkey) (SHLD-1).F() недопустимо рассчитывать вовне (MUST-9), иначе злоумышленник все равно сможет угадать порядковые номера по ISN, использованному в другом соединении. PRF можно реализовать как криптографических хэш конкатенации параметров соединения TCP и неких секретных данных. Выбор конкретного алгоритма хэширования и поддержка данных секретного ключа рассмотрены в разделе 3 [42].

Для каждого соединения имеется порядковый номер приёма и передачи. Исходный номер для передачи (initial send sequence number или ISS) выбирается передающим партнёром TCP, и исходный номер для приёма (initial receive sequence number или IRS) определяется в процедуре организации соединения.

Для организации и инициализации соединения два партнёра TCP должны синхронизировать свои начальные порядковые номера. Это выполняется путём обмена сегментами организации соединения с установленным флагом SYN (для синхронизации) и начальными номерами. Для краткости сегменты с флагом SYN называются просто SYN. Для решения задачи нужен подходящий механизм выбора начального порядкового номера и некоторое усложнение согласования (handshake) для обмена значениями ISN.

Для синхронизмции требуется отправка каждой стороной своего начального порядкового номера и приём подтверждения от удалённого партнёра TCP. Каждая сторона должна также получить начальный порядковый номер удалённого партнёра и передать соответствующее подтверждение.

  1. A –> BSYN – мой порядковый номер X;
  2. A <– BACK – ваш порядковый номер X;
  3. A <– BSYN – мой порядковый номер Y;
  4. A –> BACK – ваш порядковый номер Y.

Поскольку этапы 2 и 3 можно объединить в одно сообщение, эта процедура называется 3-этапным (three-way или three message) согласованием (handshake, 3WHS).

Согласование 3WHS требуется потому, что порядковые номера не привязаны к глобальным часам в сети и реализации TCP могут применять разные механизмы выбора ISN. Получатель первого SYN не может узнать, является ли сегмент старым, если только он не помнить последний номер, использованный в соединении (это возможно не всегда), поэтому должен запросить у отправителя проверку этого SYN. Трехэтапное согласование и преимущества схемы выбора ISN по часам рассмотрены в [69].

3.4.2. Когда нужно молчать

Существует теоретическая проблема, когда данные могут быть повреждены в результате путаницы между старыми сегментами в сети и новыми сегментами после перезагрузки хоста, если применяются те же номера портов и пространство номеров. Концепция «времени тишины» (quiet time), рассматриваемая ниже, решает эту проблему и её рассмотрение включено для ситуаций, где это уместно, хотя в большинстве современных реализаций этого не требуется. Проблема была актуальной на ранних этапах развития TCP. В современной практике Internet вероятность условия возникновения ошибок пренебрежимо мала. Причинами этого являются (a) ISS и случайное использование эфемерных портов, снижающие вероятность выбора того же номера порта и порядковых номеров после перезагрузки, (b) эффективное значение MSL в Internet снижается по мере роста скорости каналов, (c) перезагрузка зачастую длится дольше MSL.

Для гарантии того, что реализация TCP не создаст сегмент с порядковым номером, который может дублироваться в остающихся в сети старых сегментах, конечная точка TCP должна «сохранять молчание» в интервале MSL перед назначением каких-либо порядковых номеров при старте или восстановлении в ситуациях с потерей сведений о ранее использованных номерах. В этой спецификации принимается значение MSL 2 минуты. Это инженерный выбор и его можно изменить, если опыт покажет, что это желательно. Отметим, что при повторной инициализации конечной точки TCP с сохранением сведений об использованных номерах ждать не требуется, нужно лишь выбрать порядковые номера больше применяемых ранее.

3.4.3. Концепция TCP Quiet Time

Хостам, по какой-либо причине потерявшим сведения о последних переданных номерах в каждом активном (не закрытом) соединении, нужно перед отправкой какого-либо сегмента TCP выжать не менее интервала MSL согласованного в системе (сети), к которой хост относится. В последующих параграфах эта спецификация разъяснена. Разработчики TCP могут нарушать ограничение на «время тишины», но возникает риск принятия некоторых старых данных как новых или отклонения новых данных как дубликатов некоторыми получателями в системе.

Конечные точки TCP «расходуют» пространство номеров при каждом формировании сегмента и размещении его в выходной очереди передающего хоста. Алгоритм обнаружения дубликатов и упорядочения в TCP основан на однозначной привязке сегментов данных к пространству номеров так, чтобы порядковые номера не проходили весь цикл из 232 значений до того, как привязанные к номерам сегменты будут доставлены и подтверждены получателем, а все дубликаты сегментов будут «слиты» из сети. Без такого допущения два разных сегмента TCP могут получить однаковые или перекрывающиеся номера, вызывающие у получателя путаницу между старыми и новыми данными. Следует помнить, что с каждым сегментом связано множество последовательных номеров, число элементов которого совпадает с числом октетов данных и флагов SYN или FIN в сегменте.

При нормальных условиях реализация TCP отслеживает следующий порядковый номер для отправки и самый старых из ожидающих подтверждения номеров, чтобы избежать ошибочного повторного использования номера до того, как первая его передача будет подтверждена. Само по себе это не гарантирует удаления из сети старых сегментов, поэтому пространство номеров выбрано достаточно большим, чтобы снизить вероятность проблем из-за блуждающих в сети старых дубликатов. При скорости 2 Мбит/с пространство из 232 порядковых номеров расходуется за 4,5 часа. Поскольку максимальный срок жизни сегмента в сети вряд ли превысит несколько десятков секунд, это считается достаточной защитой для представимых сетей даже при росте скорости передачи данных до десятков Мбит/с. При скорости 100 Мбит/с цикл расхода номеров составляет 5,4 мнут, что намного меньше, но в пределах разумного. Сегодня доступны более высокие скорости и последствия этого описаны в конце параграфа.

Базовый механизм обнаружения дубликатов и упорядочения в TCP можно обойти, если исходная конечная точка не запоминает порядковые номера, использованные последними в данном соединении. Например, если реализация TCP начинает все соединения с порядковым номером 0, после перезагрузки хоста партнёр TCP может восстановить прежнее соединение (возможно, после устранения полуоткрытого состояния) и передавать пакеты с номерами, которые идентичны или перекрываются с номерами остающихся в сети пакетов, отправленных прежней инкарнацией того же соединения. При отсутствии сведений о порядковых номерах, используемых в конкретном соединении, спецификация TCP рекомендует источнику задерживать отправку сегментов в соединении на MSL секунд, чтобы старые сегменты из прежнего соединения могли выйти из системы.

Даже хосты, способные помнить время суток и использовать его для выбора начальных порядковых номеров, не застрахованы от этой проблемы (даже при использовании времени суток при выборе начального номера для каждой новой инкарнации соединения).

Предположим, например, что соединение начинается с порядкового номера S. пусть это соединение используется мало и в конечном итоге функция начального порядкового номер (ISN(t)) принимает значение S1 последнего сегмента, переданного этой конечной точкой TCP в конкретном соединении. Предположим теперь, что в этот момент хост перезагружается и создаёт новую инкарнацию соединения. В качестве начального номера выбирается S1 = ISN(t) – последний номер, использованный в прежней инкарнации соединения! Если восстановление произошло достаточно быстро, старые дубликаты с номерами около S1 могут быть получены из сети и восприняты как новые пакеты получателем в новой инкарнации соединения.

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

Одним из способов решения этой проблемы является преднамеренная задержка передачи сегментов на время MSL после восстановления при перезагрузке, т. е. «время тишины». Хосты, не желающие ждать и готовые к возможной путанице между старыми и новыми сегментами у данного адресата, могут отказаться от ожидания. Разработчики могут предоставить пользователям TCP возможность управления ожиданием на уровне каждого соединения или неформально реализовать «время ожидания» для всех соединений. Очевидно, что даже при выборе пользователем ожидания, в нем не будет необходимости после того, как хост проработает после загрузки хотя бы MSL секунд.

Подводя итог скажем, что каждый переданный сегмент занимает хотя бы 1 порядковый номер в пространстве номеров и использованные номера будут «заняты», пока не пройдёт MSL секунд. При перезагрузке блок, занимаемый октетами данных и флагом SYN или FIN может оставаться в находящихся в пути сегментах. Если новое соединение запускается слишком быстро и использует номера из находящихся в пути сегментов прежней инкарнации, возможно перекрытие порядковых номеров, способное вызвать путаницу у получателя.

В высокоскоростных системах циклы порядковых номеров будет короче, чем при мегабитных скоростях, которые учтены в описанном выше базовом устройстве TCP. При скорости 1 Гбит/с цикл занимает 34 секунды, при 10 Гбит/с – 3 секунды, а при 100 Гбит/с – лишь треть секунды. В таких скоростных системах опции TCP Timestamp и защита от перехода номеров через максимум (Protection Against Wrapped Sequences или PAWS) [47] обеспечивают требуемые возможности обнаружения и отбрасывания старых дубликатов.

3.5. Организация соединения

Процедура трехэтапного согласования (three-way handshake) служит для организации соединений. Обычно процедуру инициирует один партнёр TCP, а другой отвечает. Процедура работает и в случае одновременного инициирования обоими партнёрами. В этом случае каждый партнёр TCP получает сегмент SYN без подтверждения после отправки им своего SYN. Конечно, прибытие старого дубликата SYN может создать у получателя иллюзию одновременной организации соединения. Подобающее использование сегментов сброса (reset) может устранить неоднозначность.

Ниже приведено несколько примеров инициирования соединений. Хотя в примерах не показана синхронизация соединений с использованием сегментов с данными, это возможно, если принимающая сторона TCP не доставляет данные пользователю до проверки их действительности (например, данные хранятся в буфере, пока соединение не достигнет состояния ESTABLISHED с учётом того, что трехэтапное согласования снижает вероятность ложных соединений).

Простейший пример 3WHS показан на рисунке 6. каждая строка на рисунке пронумерована, стрелка вправо (–>) указывает прибытие сегмента TCP от партнёра A к партнёру B, а стрелка влево (<–) прибытие сегмента в обратном направлении. Многоточия (…) указывают сегменты, остающиеся в сети (задержанные). Комментарии приведены в скобках. Состояния соединения TCP показаны после отправки или прибытия сегмента, указанного в строке. Содержимое сегментов дано в сокращённой форме с указанием номера, флагов управления и поля ACK. Другие поля, такие как окно, адреса, данные для краткости не показаны на рисунках.

    Партнёр 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=101><ACK=301><CTL=ACK><DATA> --> ESTABLISHED

Рисунок 6. Базовое 3-этапное согласования для синхронизации соединения.


В строке 2 на рисунке 6 партнёр A начинает отправку сегмента SYN, указывающего использованием порядковых номеров начиная с 100. В строке 3 партнёр B передаёт SYN и подтверждение SYN, полученного от партнёра A. Отметим, что поле подтверждения указывает, что партнёр B ожидает порядковый номер 101, подтверждая SYN с номером 100. В строке 4 партнёр A отвечает пустым сегментом с ACK для SYN от партнёра B, а в строке 5 партнёр A передаёт данные. Отметим, что номера в строках 4 и 5 совпадают, поскольку ACK не занимает пространство порядковых номеров (если это делать, придётся подтверждать ACK).

Одновременное инициирование несколько сложнее и показано на рисунке 7. Состояния каждого из партнёров TCP проходят цикл CLOSED → SYN-SENT → SYN-RECEIVED → ESTABLISHED. Реализация TCP должна поддерживать одновременные попытки организации соединения (MUST-10).

    Партнёр TCP A                                    Партнёр TCP B
1.  CLOSED                                           CLOSED
2.  SYN-SENT     --> <SEQ=100><CTL=SYN>              ...
3.  SYN-RECEIVED <-- <SEQ=300><CTL=SYN>              <-- SYN-SENT
4.               ... <SEQ=100><CTL=SYN>              --> SYN-RECEIVED
5.  SYN-RECEIVED --> <SEQ=100><ACK=301><CTL=SYN,ACK> ...
6.  ESTABLISHED  <-- <SEQ=300><ACK=101><CTL=SYN,ACK> <-- SYN-RECEIVED
7.               ... <SEQ=100><ACK=301><CTL=SYN,ACK> --> ESTABLISHED

Рисунок 7. Одновременная синхронизация соединения.


Отметим, что реализация TCP должна отслеживать, перешло соединение в SYN-RECEIVED в результате пассивного или активного вызова OPEN (MUST-11).

Основной причиной использования трехэтапного согласования является предотвращение путаницы из-за старых дубликатов инициирования соединений. Для этого задано специальное управляющее соединение сброса (reset). Если принимающий партнёр TCP находится в несинхронизированном состоянии (SYN-SENT, SYN-RECEIVED), он возвращается в состояние LISTEN при получении приемлемого сброса. Если же партнёр TCP находится в одном из синхронизированных состояний (ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING, LAST-ACK, TIME-WAIT), он прерывает соединение и информирует пользователя. Это описано более подробно ниже при рассмотрении полуоткрытых (half-open) соединений.

    Партнёр TCP A                                        Партнёр TCP B
1.  CLOSED                                               LISTEN
2.  SYN-SENT    --> <SEQ=100><CTL=SYN>               ...
3.  (duplicate) ... <SEQ=90><CTL=SYN>               --> SYN-RECEIVED
4.  SYN-SENT    <-- <SEQ=300><ACK=91><CTL=SYN,ACK>  <-- SYN-RECEIVED
5.  SYN-SENT    --> <SEQ=91><CTL=RST>               --> LISTEN
6.              ... <SEQ=100><CTL=SYN>               --> SYN-RECEIVED
7.  ESTABLISHED <-- <SEQ=400><ACK=101><CTL=SYN,ACK>  <-- SYN-RECEIVED
8.  ESTABLISHED --> <SEQ=101><ACK=401><CTL=ACK>      --> ESTABLISHED

Рисунок 8. Восстановление при старом дубликате SYN.


Простой пример восстановления от старых дубликатов показан на рисунке 8. В строке 3 старый дубликат SYN приходит партнёру B. Тот не может сказать, что это старый дубликат и отвечает нормально (строка 4). Партнёр A обнаруживает некорректность поля ACK и возвращает RST (сброс) с полем SEQ, делающим сегмент правдоподобным. Партнёр B при получении RST возвращается в состояние LISTEN. При получении в конце концов исходного SYN (строка 6) синхронизация обрабатывается нормально. Если SYN из строки 6 приходит до RST, может происходить более сложный обмен с передачей RST в обоих направлениях.

3.5.1. Полуоткрытые соединения и другие аномалии

Организованное соединение называют полуоткрытым (half-open), если один из партнёров TCP закрыл или прервал его без ведома другого партера или стороны соединения рассинхронизированы в результате отказа или перезагрузки с потерей памяти. Такие соединения автоматически сбрасываются при попытке передачи данных в любом из направлений. Однако предполагается, что такие соединения будут необычными.

Если на сайте A соединения больше нет, попытка пользователя сайта B передать данные будет приводить к получению сайтом B управляющего сообщения reset, показывающего конечной точке сайта B наличие какой-то проблемы и ожидаемый разрыв соединения.

Предположим, что пользовательские процессы A и B взаимодействуют между собой и происходит отказ или перезагрузка с потерей памяти в реализации на стороне A. В зависимости от операционной системы, поддерживающей реализацию A, вполне вероятен некий механизм восстановления при ошибках. Когда конечная точка TCP заново активизируется, процесс A, скорей всего, запустится с начала или с точки восстановления. В результате A, вероятно, вызовет OPEN для соединения или попытается использовать для него SEND, считая соединение открытым. В последнем случае он получит сообщение об ошибке connection not open (соединение не открыто) от локальной реализации TCP A. При попытке организовать соединение реализация TCP A будет передавать сегмент с флагом SYN. Это ведёт к ситуации, показанной на рисунке 9. После перезагрузки партнёра A пользователь пытается заново организовать соединение, а партнёр B считает соединение открытым.

    Партнёр TCP A                                    Партнёр TCP B
1.  (REBOOT)                              (send 300,receive 100)
2.  CLOSED                                           ESTABLISHED
3.  SYN-SENT --> <SEQ=400><CTL=SYN>              --> (??)
4.  (!!)     <-- <SEQ=300><ACK=100><CTL=ACK>     <-- ESTABLISHED
5.  SYN-SENT --> <SEQ=100><CTL=RST>              --> (Abort!!)
6.  SYN-SENT                                         CLOSED
7.  SYN-SENT --> <SEQ=400><CTL=SYN>              -->

Рисунок 9. Обнаружение полуоткрытого соединения.


Когда SYN приходит партнёру B (строка 3), тот находится в синхронизированном состоянии, но входящий сегмент не попадает в окно и в ответ на него передаётся подтверждение, указывающее следующий ожидаемый номер (ACK 100). Партнёр A видит, что этот сегмент подтверждает данные, которых он не передавал и, будучи несинхронизированным, передаёт сбров (RST), поскольку обнаруживает полуоткрытое соединение. Партнер B прерывает соединение в строке 5. Партнёр A продолжает попытку организовать соединение, используя базовое 3-этапное согласование (Рисунок 6).

Интересный вариант возникает, когда партнёр A перезагружается, а B пытается передать данные, считая соединение синхронизированным (Рисунок 10). В этом случае данные, прибывшие партнёру A от партнёра B (строка 2) не приемлемы, поскольку соединения нет, поэтому партнёр A передаёт RST. Сегмент RST приемлем для B и тот обрабатывает его, разрывая (abort) соединение.

    Партнёр TCP A                                        Партнёр TCP B
1.  (REBOOT)                                  (send 300,receive 100)
2.  (??)    <-- <SEQ=300><ACK=100><DATA=10><CTL=ACK> <-- ESTABLISHED
3.          --> <SEQ=100><CTL=RST>                   --> (ABORT!!)

Рисунок 10. Активная сторона вызывает обнаружение полуоткрытого соединения.


На рисунке 11 показаны партнёры TCP A и B с пассивными соединениями, ожидающими SYN. Прибытие старого дубликата (строка 2) побуждает партнёра B действовать. Он возвращает SYN-ACK (сторока 3), который вызывает у партнера A генерацию RST (ACK в строке 3 не приемлем). Партнер Peer B воспринимает сброс и возвращается в состояние LISTEN.

    Партнёр TCP A                                 Партнёр TCP B
1.  LISTEN                                        LISTEN
2.       ... <SEQ=Z><CTL=SYN>                -->  SYN-RECEIVED
3.  (??) <-- <SEQ=X><ACK=Z+1><CTL=SYN,ACK>   <--  SYN-RECEIVED
4.       --> <SEQ=Z+1><CTL=RST>              -->  (return to LISTEN!)
5.  LISTEN                                        LISTEN

Рисунок 11. Старый дубликат SYN вызывает Reset на двух пассивных сокетах.


Возможны другие варианты и все они обрабатываются по приведённым ниже правилам создания и обработки RST.

3.5.2. Генерация Reset

Пользователь или приложение TCP может инициировать сброс соединения в любой момент с помощью события reset, кроме того, такие события может генерировать сам протокол при возникновении ошибок, как указано ниже. Инициировавшей сброс стороне соединения следует перейти в состояние TIME-WAIT, поскольку это обычно помогает снизить нагрузку на загруженные серверы по причинам, описанным в [70].

Как правило сброс (RST) передаётся всякий раз при получении сегмента, который представляется не предназначенным для текущего соединения. Сброс недопустимо инициировать, если не очевидно, что это так.

Имеется три группы состояний, описанных ниже.

  1. Если соединения не существует (CLOSED), сброс передаётся в ответ на любой входящий сегмент, за исключением reset. Таким образом, сегмент SYN не соответствующий имеющемуся соединению, отвергается.

    Если во входящем сегменте установлен флаг ACK, сброс принимает порядковый номер из поля ACK в сегменте, в иных случаях сброс имеет номер 0, а в поле ACK помещается сумма порядкового номера и размера входящего сегмента. Соединение сохраняет состояние CLOSED.

  2. Если соединение находится в несинхронизированном состоянии (LISTEN, SYN-SENT, SYN-RECEIVED) и входящий сегмент подтверждает что-то ещё не отправленное (содержит неприемлемое значение ACK), имеет уровень защиты или изоляции (compartment, A.1. IP Security Compartment и Precedence) не соответствуют запрошенному для соединения уровню изоляции, передаётся сброс.

    Если во входящем сегменте установлен флаг ACK, сброс принимает порядковый номер из поля ACK в сегменте, в иных случаях сброс имеет номер 0, а в поле ACK помещается сумма порядкового номера и размера входящего сегмента. Соединение сохраняет своё состояние.

  3. Если соединение находится в синхронизированном состоянии (ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING, LAST-ACK, TIME-WAIT), на любой неприемлемый сегмент (номер за пределами окна или неприемлемый номер подтверждения) должен возвращаться пустой сегмент подтверждения (без пользовательских данных) с текущим порядковым номером передачи и подтверждением, указывающим ожидаемый следующим на приёме номер, а соединение остаётся в прежнем состоянии.

    Если входящий сегмент имеет уровень защиты или изоляцию, не соответствующие установленному для соединения, передаётся сброс и соединение переходит в состояние CLOSED. Для сброса применяется порядковый номер из поля ACK во входящем сегменте.

3.5.3. Обработка Reset

В любом состоянии, кроме SYN-SENT, все сегменты сброса (RST) проверяются по полям SEQ. Сброс действителен, если его номер попадает в окно. В состоянии SYN-SENT (RST принимается в ответ на начальный SYN) сегмент RST может быть воспринят, если поле ACK подтверждает SYN.

Получатель RST сначала проверяет сегмент, затем меняет состояние. Если получатель был в состоянии LISTEN, он игнорирует сброс. Если получатель был в состоянии SYN-RECEIVED, а ранее – в LISTEN, он возвращается в состояние LISTEN, в иных случаях – прерывает соединение и переходит в состояние CLOSED. Если получатель был в любом другом состоянии, он прерывает соединение, уведомляя пользователя, и переходит в состояние CLOSED.

Реализациям TCP следует разрешать включение данных в сегмент RST (SHLD-2). Высказаны предложение по включению в RST диагностических данных, объясняющих причину RST. Для таких данных ещё нет стандарта.

3.6. Закрытие соединения

Операция CLOSE означает: «У меня больше нет данных для передачи.» Понятие закрытия полнодуплексного соединения можно толковать по-разному, поскольку может быть не очевидно, как трактовать принимающую сторону соединения. Поэтому выбрана симплексная трактовка CLOSE. Пользователь, применяющий CLOSE, может продолжать RECEIVE, пока получателю TCP не будет сказано, что удалённый партнёр также перешёл в состояние CLOSED. Таким образом, программа может инициировать несколько SEND, за которыми следует CLOSE и после этого продолжать RECEIVE, пока не будет сигнала о невозможности RECEIVE по причине перехода удалённого партнёра в состояние CLOSED. Реализация TCP будет сигнализировать пользователю о закрытии удалённого партнёра даже при отсутствии остающихся RECEIVE, поэтому пользователь может аккуратно завершить работу на своей стороне. Реализация TCP будет гарантированно доставлять все буферы SENT до перехода в состояние CLOSED, поэтому пользователю, не ожидающему данных в ответ, достаточно лишь подождать сведений о переходе соединения в состояние CLOSED, чтобы знать о доставке всех данных удалённой точке TCP. Пользователи должны продолжать считывание соединения, пока реализация TCP не укажет, что данных больше нет.

Здесь следует рассмотреть три особых случая:

  1. действие пользователя, просящего реализацию TCP закрыть (CLOSE) соединение (TCP Peer A на рисунке 12);

  2. передача удалённой точкой TCP сигнала управления FIN (TCP Peer B на рисунке 12);

  3. оба пользователя одновременно применяют CLOSE (Рисунок 13).

Инициатива пользователя по закрытию

В этом случае сегмент FIN может быть создан и помещён в очередь исходящих сегментов. Дальнейшие SEND от пользователя реализация TCP не воспринимает и переходит в состояние FIN-WAIT-1. В этом состоянии разрешены RECEIVE. Все прежние сегменты, включая FIN будут передаваться (повторно), пока не будут подтверждены. Когда удалённый партнёр TCP подтвердил FIN и передал свой сегмент FIN, первый партнёр TCP может подтвердить (ACK) этот сегмент FIN. Отметим, что получившая FIN конечная точка TCP будет передавать ACK но не будет передавать свой сегмент FIN, пока пользователь не закрыл соединение (CLOSED).

Получение конечной точкой TCP сегмента FIN из сети

Если из сети приходит незапрошенный сегмент FIN, принимающая конечная точка TCP может подтвердить его (ACK) и сообщить пользователю о закрытии соединения. Пользователь будет отвечать вызовом CLOSE, по которому конечная точка может передать FIN партнёру TCP после отправки остающихся данных. Конечная точка TCP может ждать подтверждения своего сегмента FIN, после чего удалит соединение. Если ACK не приходит, соединение прерывается по тайм-ауту пользователя и тот уведомляется об этом.

Одновременное закрытие соединения пользователями

Одновременный вызов CLOSE пользователями на обеих сторонах соединения вызывает обмен сегментами FIN (Рисунок 13). Когда все сегменты, предшествующие FIN обработаны и подтверждены, каждый из партнёров TCP может подтвердить (ACK) полученный сегмент FIN. При получении ACK оба будут удалять соединение.


    Партнёр TCP A                                        Партнёр TCP B
1.  ESTABLISHED                                          ESTABLISHED
2.  (Close)
    FIN-WAIT-1  --> <SEQ=100><ACK=300><CTL=FIN,ACK>  --> CLOSE-WAIT
3.  FIN-WAIT-2  <-- <SEQ=300><ACK=101><CTL=ACK>      <-- CLOSE-WAIT
4.                                                       (Close)
    TIME-WAIT   <-- <SEQ=300><ACK=101><CTL=FIN,ACK>  <-- LAST-ACK
5.  TIME-WAIT   --> <SEQ=101><ACK=301><CTL=ACK>      --> CLOSED
6.  (2 MSL)
    CLOSED

Рисунок 12. Последовательность нормального закрытия.

    Партнёр TCP A                                        Партнёр TCP B
1.  ESTABLISHED                                          ESTABLISHED
2.  (Close)                                              (Close)
    FIN-WAIT-1  --> <SEQ=100><ACK=300><CTL=FIN,ACK>  ... FIN-WAIT-1
                <-- <SEQ=300><ACK=100><CTL=FIN,ACK>  <--
                ... <SEQ=100><ACK=300><CTL=FIN,ACK>  -->
3.  CLOSING     --> <SEQ=101><ACK=301><CTL=ACK>      ... CLOSING
                <-- <SEQ=301><ACK=101><CTL=ACK>      <--
                ... <SEQ=101><ACK=301><CTL=ACK>      -->
4.  TIME-WAIT                                            TIME-WAIT
    (2 MSL)                                              (2 MSL)
    CLOSED                                               CLOSED

Рисунок 13. Последовательность одновременного закрытия.


Соединение TCP может разрываться двумя способами: (1) нормальная последовательность закрытия TCP с применением обмена FIN (Рисунок 12) и (2) прерывание (abort) с передачей одного или нескольких сегментов RST и немедленным отбрасыванием состояния соединения. Если локальное соединение TCP закрыто удалённой точкой с помощью передачи FIN или RST, локальное приложение должно быть проинформировано о нормальном завершении или прерывании (MUST-12).

3.6.1. Полузакрытые соединения

При нормальной последовательности завершения TCP буферизованные данные гарантированно длставляются в обоих направлениях. Поскольку каждое направление в TCP закрывается независимо, созможны полузакрытые (half closed) соединения (т. е. закрыто лишь одно направление), когда хост может продолжать передачу данных в открытом направлении полузакрытого соединения.

Хост может реализовать полудуплексную последовательность закрытия TCP так, что вызвавшее CLOSE приложение может читать данные из соединения (MAY-1). Если такой хост получает вызов CLOSE и в соединении ещё остаются ожидающие приёма данные или новые данные получены после вызова CLOSE, реализации TCP на этом хосте следует передать RST для индикации потери данных (SHLD-3). Это рассмотрено в параграфе 2.17 [23].

Когда соединение закрывается активно, оно должно сохранять состояние TIME-WAIT в течение 2xMSL (максимальный срок жизни сегмента) (MUST-13). Однако оно может воспринять новый сегмент SYN от удалённой точки TCP для повторного открытия соединения напрямую из состояния TIME-WAIT (MAY-2)

  1. если в новом соединении задан начальный порядковый номер больше максимального номера в прежнем соединении, создаётся новое соединение;

  2. если SYN оказывается старым дубликатом, сохраняется состояние TIME-WAIT.

При доступности опций TCP Timestamp улучшенный алгоритм [40] повышает скорость организации соединений. Этот алгоритм сокращения TIME-WAIT, основанный на опыте (Best Current Practice), следует применять, поскольку опции Timestamp используются широко и это снижает TIME-WAIT, что важно для загруженных серверов Internet (SHLD-4).

3.7. Сегментация

Термин сегментация обозначает действия TCP, выполняемые при восприятии потока байтов от передающего приложения и пакетизации этого потока абйтов в сегменты TCP. Отдельные сегменты TCP зачастую не отображаются «один к одному» в отдельные вызовы send (или записи в сокет) из приложения. Приложения могут выполнять запись на уровне сообщений в протоколе вышележащего уровня, но TCP не гарантирует сопоставления границ передаваемых и принимаемых сегментов TCP с границами буферов чтения и записи данных пользовательского приложения. В некоторых протоколах, таких как удалённый прямой доступ к памяти (Remote Direct Memory Access или RDMA) с использованием прямого размещения данных (Direct Data Placement или DDP) и маркерного кадрирования с выравниванием PDU (Marker PDU Aligned Framing или MPA) [34], возможна оптимизация производительности при доступности контроля над сопоставлением сегментов TCP и блоков данных приложенийа MPA включает конкретный механизм обнаружения и проверки взаимосвязи между сегментами TCP и структурами данных пользовательских сообщений, но этот метод специфичен для таких приложений, как RDMA. В общем случае на размер сегментов, создаваемых реализацией TCP влияет множество целей и параметров.

Цели, ведущие к отправке больших сегментов, включают:

  • снижение числа находящихся в сети пакетов;

  • повышение эффективности обработки и возможной производительности за счёт меньшего числа прерываний и межуровневых взаимодействий;

  • снижение издержек, связанных с заголовками TCP.

Отметим, что выигрыш в производительности за счёт роста размеров может сокращаться по мере увеличения и возможны границы, после которых рост размера будет снижать производительность. Например, в реализациях для некоторых вариантов архитектуры производительность при размере сегмента 1025 байтов может быть ниже, чем при 1024 байтах в результате выравнивания данных при операциях копирования.

Цели, ведущие к снижению размера сегментов, включают:

  • предотвращение передачи сегментов TCP, которые ведут к размеру дейтаграмм IP больше минимального MTU на пути через сеть IP, что ведёт к потере или фрагментации дейтаграмм, кроме того, некоторые межсетевые экраны и промежуточные устройства могут отбрасывать фрагменты пакетов или связанные с ними сообщения ICMP;

  • предотвращение задержки потока данных приложения, особенно в случае ожидания протоколом TCP от приложения генерации дополнительных данных или ожидании приложением события или входных данных от партнёра для генерации последующих данных;

  • разрешение «общей судьбы» (fate sharing) для сегментов TCP и блоков данных нижележащего уровня (например, ниже IP для каналов с ячейками или кадрами меньше IP MTU).

Для согласования этих противоречивых целей в TCP включено несколько механизмов, таких как опция максимального размера сегмента (Maximum Segment Size или MSS), Path MTU Discovery, алгоритм Nagle и поддержка IPv6 Jumbogram, которые описаны в последующих параграфах.

3.7.1. Максимальный размер сегмента (MSS)

Конечные точки TCP должны реализовать приём и передачу опции MSS (MUST-14).

Реализациям TCP следует передавать опцию MSS в каждом сегменте SYN при MSS для приёма меньше принятого по умолчанию значения 536 для IPv4 и 1220 для IPv6 (SHLD-5) и можно передавать её всегда (MAY-3).

Если опция MSS не получена при организации соединения, реализация TCP должна предполагать принятое по умолчанию значение MSS 536 (576 – 40) для IPv4 и 1220 (1280 – 60) для IPv6 (MUST-15).

Максимальный размер передаваемого конечной точкой TCP сегмента или эффективное значение MSS для передачи (effective send MSS) должно быть меньшим из значений (MUST-16) SendMSS (отражает доступный размер буфера сборки на приёмной стороне EMTU_R [19]) и наибольшим размером передачи, разрешаемым уровнем IP (EMTU_S [19])

 Eff.snd.MSS = min(SendMSS+20, MMS_S) - TCPhdrsize - IPoptionsize

с учётом приведённых ниже сведений.

  • SendMSS – значение MSS, полученное от удалённого хоста или принятый по умолчанию размер 536 для IPv4 и 1220 для IPv6, если опция MSS не была получена.

  • MMS_S – максимальный размер сообщения транспортного уровня, которое может передать TCP.

  • TCPhdrsize – размер фиксированного заголовка TCP и всех опций. Это 20 в (редком) случае отсутствия опций и увеличивается при добавлении опций TCP. Отметим, что некоторые опции могут включаться не во все сегменты и при передаче каждого сегмента отправителю следует корректировать значение в Eff.snd.MSS.

  • IPoptionsize – размер всех опций IPv4 или заголовков расширения IPv6, связанных с соединением TCP. Отметим, что некоторые опции и заголовки расширения могут включаться не во все сегменты и при передаче каждого сегмента отправителю следует корректировать значение в Eff.snd.MSS.

Значению MSS для передачи в опции MSS следует указывать эффективное значение MTU за вычетом фиксированных заголовков IP и TCP. При игнорировании опций IP и TCP в расчёте значения опции MSS и наличии в пакете каких-либо опций IP или TCP отправитель должен соответственно сократить размер данных TCP (см. RFC 6691 [43]).

Значение MSS для передачи в опции MSS должно быть не больше MMS_R – 20, где MMS_R – максимальный размер сообщения транспортного уровня, которое может быть принято (и собрано на уровне IP) (MUST-67). TCP получает значения MMS_R и MMS_S от уровня IP (см. базовый вызов GET_MAXSIZES в параграфе 3.4 RFC 1122). Эти значения определены на основе эквивалентов IP MTU – EMTU_R и EMTU_S [19].

При использовании TCP в ситуации с переменным размером заголовков IP или TCP отправитель должен уменьшить количество данных TCP в данном пакете на число октетов в опциях IP и TCP. С этим связана историческая путаница, рассмотренная в параграфе 3.1 RFC 6691.

3.7.2. Определение Path MTU

Реализация TCP может знать MTU подключённых напрямую каналов, но очень редко имеет сведения о MTU всех путей через сеть. Для IPv4 в RFC 1122 рекомендуется применять на уровне IP по умолчанию MTU не более 576 для адресатов, не подключённых напрямую, а для IPv6 значение составляет 1280. Использование этих фиксированных значений ограничивает производительность и эффективность соединения TCP. Взамен настоятельно рекомендуется реализовать механизм определения MTU для пути (Path MTU Discovery или PMTUD) и обнаружение MTU уровня пакетизации для пути (Packetization Layer Path MTU Discovery или PLPMTUD) в TCP, чтобы сделать сегментацию более эффективной. Оба механизма PMTUD и PLPMTUD помогают TCP выбрать размер сегментов так, чтобы избежать фрагментации в пути (IPv4) или у отправителя (IPv4 и IPv6).

PMTUD для IPv4 [2] или IPv6 [14] реализуется в сочетании TCP, IP и ICMP. Механизм основан на предотвращении фрагментации у отправителя и установке флага IPv4 DF (не фрагментировать), позволяющего предотвратить фрагментацию в пути. Механизм опирается на сообщения ICMP от маршрутизаторов в пути, передаваемые, когда сегмент слишком велик для передачи через канал. Некоторые настройки реализации TCP при использовании PMTUD описаны в RFC 2923 и позволяют решить возникающие на практике проблемы [27]. PLPMTUD [31] является стандартным (Standards Track) развитием PMTUD, смягчающим требования к поддержке ICMP на пути и повышающим производительность в случаях, когда сообщения ICMP не передаются согласованно, с сохранением передачи без фрагментации. Механизмы во всех 4 упомянутых RFC рекомендуется включать в реализации TCP.

Опция TCP MSS задаёт верхнюю границу размера пакетов, которые могут быть приняты (см. [43]). Поэтому установка соишком малого значения опции MSS может влиять на способность PMTUD и PLPMTUD найти большие значения path MTU. В RFC 1191 обсуждается последствие установки в старых реализациях TCP значения TCP MSS = 536 (соответствует IPv4 MTU в 576 байтов) для нелокальных получателей вместо вывода его из MTU подключённых интерфейсов, как это рекомендуется.

3.7.3. Интерфейсы с переменным значением MTU

Эффективное значение MTU может иногда меняться, например, при использовании переменного сжатия, такого как ROHC (RObust Header Compression) [37]. Для реализации TCP заманчиво объявить наибольшее возможное значение MSS, чтобы поддерживать наиболее эффективное использование сжатых данных. К сожалению, некоторым схемам сжатия иногда требуется передавать полные заголовки (и меньше полезных данных) при ресинхронизации состояния на компрессорах и декомпрессорах конечных точек. Если использовать наибольшее значение MTU при расчёте анонсируемого значения опции MSS, повторная передача TCP может помещать ресинхронизации компрессора.

В результате при смене MTU на интерфейсе от пакета к пакету реализации TCP следует применять наименьшее значение MTU интерфейса при расчёте значения опции MSS (SHLD-6).

3.7.4. Алгоритм Nagle

Алгоритм Nagle описан в RFC 896 [17] и был рекомендован в RFC 1122 [19] для смягчения проблемы создания слишком большого числа мелких пакетов. Алгоритм реализован с большинстве современных баз кода TCP, иногда с теми или иными вариациями (см. A.3. Изменение алгоритма Nagle).

При наличии неподтвержденных данных (SND.NXT > SND.UNA) передающая конечная точка TCP буферизует все данные пользователя (независимо от бита PSH) пока остающиеся данные не будут подтверждены или конечная точка сможет передать полный сегмент TCP (Eff.snd.MSS байт).

Реализации TCP следует включать алгоритм Nagle для объединения коротких сегментов (SHLD-7). Однако у приложения должен быть способ отключить алгоритм Nagle на отдельном соединении (MUST-17). В любом случае отправка данных происходит с учётом ограничений, задаваемых алгоритмом замедленного старта [8].

Поскольку при взаимодействии алгоритма Nagle с отложенными подтверждениями могут возникать проблемы, некоторые реализации несколько изменяют алгоритм Nagle, например, как описано в Приложении A.3.

3.7.5. Джамбограммы IPv6

Для поддержки TCP с использованием IPv6 Jumbogram реализация должна быть способна передавать сегменты TCP размером больше 64 Кбайт, которые позволяет указать опция MSS. В RFC 2675 [24] указано, что значение MSS = 65535 байт считается бесконечным и применяется Path MTU Discovery [14] для определения фактического MSS.

Опцию Jumbo Payload не обязаны реализовать и понимать узлы IPv6, не поддерживающие подключение к каналам с MTU больше 65575 [24], а действующие требования к узлам IPv6 не включают поддержку Jumbogram [55].

3.8. Обмен данными

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

Отправитель данных сохраняет порядковый номер для следующей передачи в переменной SND.NXT, а старейший из неподтвержденных порядковых номеров – в переменной SND.UNA. Получатель данных хранит следующий ожидаемый номер в переменной RCV.NXT. Если все данные сразу же подтверждаются, значения этих 3 переменных совпадают.

Когда отправитель создает сегмент и передаёт его, он увеличивает значение SND.NXT. Получатель при приёме сегмента увеличивает RCV.NXT и передаёт подтверждение. При получении подтверждения отправителем, тот увеличивает SND.UNA. Степень различия этих переменных является мерой задержки в коммуникациях. Размер увеличения переменных определяется суммарным размером данных и флага SYN или FIN в сегменте. Отметим, что после достижения состояния ESTABLISHED все сегменты должны содержать данные подтверждения.

Пользовательский вызов CLOSE предполагает функцию выталкивания (push) (параграф 3.9.1. Интерфейс TCP – пользователь), как при флага FIN во входящем сегменте.

3.8.1. Тайм-аут повтора передачи

Из-за изменчивости сетей, образующих многосетевую (internetwork) систему и широкого спектра применения соединений TCP тайм-аут повтора передачи (retransmission timeout или RTO) должен задаваться динамически. Значение RTO должно рассчитываться по алгоритмам из [10], включая алгоритм Karn для выборки RTT (MUST-18).

В RFC 793 приведена процедура расчёта RTO на основе работы, упомянутой в IEN 177 [71]. Это было заменено алгоритмом, описанным в RFC 1122, который был обновлён в RFC 2988, а затем – в RFC 6298.

RFC 1122 говорит, что при повторной передаче пакета, идентичного исходному (это предполагает совпадение не только границ данных, но и полей заголовка), можно использовать то же поле IPv4 Identification (см. параграф 3.2.1.5 в RFC 1122) (MAY-4). Одно и то же поле IP Identification можно применять повторно в любом случае, поскольку оно имеет значение лишь при фрагментации дейтаграмм [44]. Реализациям TCP не следует полагаться на это поле заголовка и обычно даже взаимодействовать с ним. Это неразумный способ указания передачи и получения дубликатов.

3.8.2. Контроль перегрузок TCP

В RFC 2914 [5] разъяснена важность контроля перегрузок в Internet.

RFC 1122 требует реализовать алгоритмы Van Jacobson для контроля перегрузок – замедленный старт (slow start) и предотвращение перегрузки (congestion avoidance) вместе с экспоненциальной отсрочкой (backoff) в последовательных RTO для одного и того же сегмента. В RFC 2581 дано стандартизованное (IETF Standards Track) описание slow start и congestion avoidance, а также механизмов ускоренного повтора (fast retransmit) и быстрого восстановления (fast recovery). RFC 5681 содержит текущее описание этих алгоритмов и текущую спецификацию Standards Track с рекомендациями по контролю перегрузок в TCP. В RFC 6298 описана экспоненциальная отсрочка для значений RTO, включая сохранение отложенного значения, пока последующий сегмент с новыми данными не будет передан и подтверждён без повтора передачи.

Конечная точка TCP должна реализовать базовые алгоритмы контроля перегрузок slow start, congestion avoidance и экспоненциальной отсрочки RTO для предотвращения условий коллапса насыщения (MUST-19). В RFC 5681 и RFC 6298 описаны широко применяемые базовые алгоритмы (IETF Standards Track). Имеется много других подходящих алгоритмов, которые широко распространены. Многие реализации TCP поддерживают набор разных алгоритмов, которые можно настроить для применения на конечной точке. Такие дополнительные алгоритмы можно реализовать при условии их соответствия спецификациям TCP из IETF Standards Track, как описано в RFC 2914, RFC 5033 [7], RFC 8961 [15] (MAY-18).

Явное уведомление о перегрузке (Explicit Congestion Notification или ECN) было определено в RFC 3168 и является усовершенствованием IETF Standards Track, имеющим много преимуществ [51]. Конечной точке TCP следует реализовать ECN, как описано в RFC 3168 (SHLD-8).

3.8.3. Отказы соединений TCP

Чрезмерные повторы передачи одного сегмента конечной точкой TCP говорят о том или ином отказе на удалённом хосте или в пути через сеть. Этот отказ может быть краткосрочным или продолжительным. Описанные ниже процедуры должны применяться при обработке чрезмерных повторов передачи сегментов данных (MUST-20).

  1. Имеется два пороговых значения R1 и R2 при измерении числа повторов передачи одного сегмента. R1 и R2 можно измерять по времени или числу повторов (с текущим RTO и соответствующей экспоненциальной отсрочкой в качестве коэффициента преобразования, при необходимости).

  2. Когда число повторов передачи одного сегмента становится не меньше порога R1, передаётся рекомендация (см. параграф 3.3.1.4 в [19]) уровню IP для вызова диагностики «мертвого шлюза».

  3. Когда число повторов передачи одного сегмента достигает порога R2 (> R1), соединение закрывается.

  4. Приложение должно (MUST-21) быть способно устанавливать порог R2 для конкретного соединения. Например, интерактивное приложение может установить для R2 значение infinity (бесконечно), отдающее пользователю управления разрывом соединения.

  5. Реализациям TCP следует информировать приложение о проблемах доставки (если это не отключено приложением, см. параграф 3.9.1.8. Асинхронные отчёты), по достижении порога R1 и до R2 (SHLD-9). Это позволит информировать пользователя, например, в программе удалённой регистрации в системе (login).

Значению R1 следует соответствовать по меньшей мере 3 повторам передачи при текущем значении RTO (SHLD-10). Для R2 следует устанавливать значение не менее 100 секунд (SHLD-11).

Попытка организации соединения TCP может приводить к отказу из-за чрезмерного повтора передачи сегмента SYN, получения сегмента RST или сообщения ICMP Port Unreachable. Повторы передачи SYN должны обрабатываться в общем порядке, приведённом выше для повторов, включая уведомление прикладного уровня. Однако значения R1 и R2 для SYN и сегментов данных могут различаться. В частности значение R2 для сегмента SYN должно быть достаточно большим, чтобы обеспечивать повтор передачи сегмента в течение по меньшей мере 3 минут (MUST-23). Приложение, естественно, может закрыть соединение (отказаться от попытки соединиться) раньше.

3.8.4. TCP Keep-Alive

Соединение TCP считается бездействующим (idle), если в течение некоторого времени через него не было принято ни одного входящего сегмента и передано новых или неподтверждённых данных.

Разработчики могут включать сообщения keep-alive в свои реализации TCP (MAY-5), хотя такая практика не является общепринятой. Некоторые реализации TCP, тем не менее, применяют механизм keep-alive для сохранения активности бездействующего соединения, передавая пробный сегмент, предназначенный для получения ответа от партнёра TCP. Такие сегменты обычно включают SEG.SEQ = SND.NXT-1 и могут содержать «сорные» октеты данных. Если сообщения keep-alive применяются, приложение должно быть способно включать и отключать их передачу для каждого соединения TCP (MUST-24) и по умолчанию сообщения должны быть отключены (MUST-25).

Пакеты keep-alive должны передаваться лишь при отсутствии данных для передачи и отсутствии принятых пакетов данных или подтверждений в течение заданного интервала (MUST-26), который должен быть настраиваемым (MUST-27) и по умолчанию должен составлять не менее 2 часов (MUST-28).

Очень важно помнить, что сегменты ACK без данных не передаются TCP с гарантией. Поэтому при реализации механизма keep-alive недопустимо рассматривать отсутствие отклика на конкретный тестовый пакет признаком «метвого» соединения (MUST-29).

Реализации следует передавать сегменты keep-alive без данных (SHLD-12), однако можно поддерживать настраиваемую передачу сегментов keep-alive с 1 октетом «сорных» данных (MAY-6) для совместимости с ошибочными реализациями TCP.

3.8.5. Обмен важными сведениями

Из-за различий в реализациях и взаимодействии с промежуточными устройствами новым приложениям не следует реализовать механизм TCP urgent (SHLD-13). Однако реализации TCP должны включать поддержку механизма срочности (MUST-30). Сведения об интерпретации некоторыми реализациями TCP указателя важности (срочности) приведены в RFC 6093 [39].

Цель механизма TCP urgent состоит в предоставлении передающему пользователю возможности стимулировать принимающего пользователя к восприятию неких важных (срочных) данных, а приёмной точке TCP – указать пользователю, когда все известные в данный момент важные данные будут получены им. Этот механизм позволяет указать в потоке данных точку, задающую конец важных данных. Всякий раз, когда эта точка опережает порядковый номер приёма (RCV.NXT) на принимающей стороне TCP, реализация TCP должна указать пользователю переход в режим срочности (urgent mode). Когда порядковый номер приёма «догоняет» указатель важности, реализация TCP должна указать пользователю переход в обычный режим. Если указатель важности меняется во время пребывания пользователя в режиме urgent, это обновление будет незаметно для пользователя.

Метод использует поле Urgent во всех передаваемых сегментах, а флаг URG указывает значимость этого поля и должен устанавливаться в сегментах, фактически содержащих указатель важности. Отсутствие флага говорит, что важных (срочных) данных в сегменте нет.

Для отправки важной информации пользователь должен передать хотя бы 1 октет. Если передающий пользователь указывает также выталкивание (push), это улучшает своевременность доставки важных данных целевому процессу. Поскольку указатель важности соответствует данным, записанным передающим приложением, значение указателя важности не может «отступить» в пространстве порядковых номеров, но получателям TCP следует быть устойчивыми к некорректному поведению указателя важности.

Реализации TCP должны поддерживать последовательности важных данных любого размера (MUST-31) [19].

Указатель важности должен содержать порядковый номер октета, следующего за важными данными (MUST-62).

Реализация TCP должна (MUST-32) асинхронно информировать уровень приложения о получении указателя важности (если ранее важных данных не было) или перемещении указателя важности вперёд. Реализация TCP должна (MUST-33) обеспечивать приложениям способ узнать объем остающихся в соединении важных данных или хотя бы определить остаются ли ещё важные данные для считывания [19].

3.8.6. Управление окном

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

Передающая сторона TCP пакует данные для передачи в сегменты, заполняющие текущее окно, и может перепаковывать сегменты в очереди повторной передачи. Такая перепаковка не требуется, но может быть полезной.

В соединении с односторонним потоком данных информация об окне передаётся в сегментах подтверждения с одним порядковым номером, поэтому их порядок невозможно поменять при нарушении порядка доставки. Это не является серьёзной проблемой, но может время от времени давать сведения об окне по старым «отчетам» от получателя. Позволяющее избежать этой проблемы усовершенствование состоит в том, чтобы брать информацию об окне из сегмента с наибольшим порядковым номером подтверждения (т. е. с номером не меньше наибольшего из принятых последними).

Указание большего окна стимулирует передачу. Если поступает больше данных, чем можно воспринять, они будут отбрасываться. Это ведёт к избыточным повторам передачи, повышая загрузку сети и конечных точек TCP. Указание малого окна ограничивает передачу данных до такой степени, что может добавляться задержка в интервал кругового обхода (round-trip) между передачами сегментов.

Имеющиеся механизмы позволяют конечной точке TCP анонсировать большое окно, а затем анонсировать его уменьшение, не принимая так много данных. Так называемое «сокращение окна» (shrinking the window) настоятельно не рекомендуются. Принцип отказоустойчивости [19] диктует партнёрам TCP не сокращать окно самостоятельно, но быть готовыми в такому поведению партнёра TCP.

Получателю TCP не следует сокращать окно, т. е. сдвигать его правый край влево (SHLD-14). Однако передающий партнёр TCP должен быть готов к такому сокращению, которое может сделать размер доступного окна (usable window, см. 3.8.6.2.1. Алгоритм отправителя – когда передавать данные) отрицательным (MUST-34). Если это происходит, отправителю не следует передавать новых данных (SHLD-15), но следует обычным способом повторить передачу неподтвержденных данных из интервала SND.UNA – SND.UNA+SND.WND (SHLD-16). Отправитель может также повторить старые данные сверх SND.UNA+SND.WND (MAY-7), но не следует фиксировать тайм-аут соединения, если данные за пределами правого края окна не подтверждены (SHLD-17). Если окно сокращается до 0, реализация TCP должна проверять его стандартным способом, описанным в следующем параграфе (MUST-35).

3.8.6.1. Проверка нулевого окна

Передающий партнёр TCP должен регулярно отправлять хотя бы 1 октет новых данных (при наличии) или повторно передавать данные принимающему партнёру TCP даже при нулевом размере окна с целью зондирования (probe) окна. Эти повторы передачи важны для гарантии того, что при установке одним из партнёров TCP нулевого размера окна это будет надёжно сообщено другому партнёру. В других документах это называется зондированием нулевого окна (Zero-Window Probing или ZWP). Зондирование (предложенных) нулевых окон должно поддерживаться (MUST-36).

Реализация TCP может сохранять предлагаемое окно приёма закрытым неограниченно долго (MAY-8). Пока принимающий партнёр TCP продолжает передавать подтверждения в ответ на сегменты зондирования, передающий партнёр TCP должен позволять соединению оставаться открытым (MUST-37). Это позволяет TCP работать в таких ситуациях, как отсутствие бумаги в принтере, описанное в параграфе 4.2.2.17 [19]. Поведение зависит от концепций управления ресурсами в реализации, как указано в [41].

Когда сегмент приходит принимающему партнёру TCP с нулевым окном, тот должен передать подтверждение, показывающее следующий ожидаемый порядковый номер и текущее окно (0). Передающему хосту следует отправлять первую пробу (зонд) наличия нулевого окна, когда такое окно существует в течение тайм-аута повтора передачи (SHLD-29) (см. параграф 3.8.1. Тайм-аут повтора передачи), а интервал между пробами следует увеличивать экспоненциально (SHLD-30).

3.8.6.2. Предотвращение SWS

«Синдром глупого окна» (Silly Window Syndrome или SWS) – это устойчивая картина небольших пошаговых изменений окна, приводящая к крайне низкой производительности TCP. Алгоритмы предотвращения SWS приведены ниже для передающей и принимающей стороны. Более подробное рассмотрение проблемы приведено в RFC 1122. Отметим, что алгоритм Nagle и алгоритм предотвращения SWS у отправителя дополняют друг друга в повышении производительности. Алгоритм Nagle препятствует отправке крошечных сегментов, когда данные для передачи поступают мелкими порциями, а алгоритм предотвращения SWS препятствует отправке мелких сегментов, возникающих в результате небольшого расширения окна справа.

3.8.6.2.1. Алгоритм отправителя – когда передавать данные

Реализация TCP должна включать алгоритм предотвращения SWS у отправителя (MUST-38). Алгоритм Nagle из параграфа 3.7.4 позволяет объединять короткие сегменты.

Алгоритм предотвращения SWS у отправителя может оказаться сложнее, чем у получателя, поскольку отправитель не знает (напрямую) общее буферное пространство получателя (RCV.BUFF). Было обнаружено, что хорошо работает подход на основе расчёта отправителем значения Max(SND.WND), которое определяет максимальное окно передачи, наблюдавшееся до этого в соединении, и использовании этого значения как оценки RCV.BUFF. К сожалению это лишь оценка и получатель в любой момент может изменить RCV.BUFF. Чтобы избежать в результате тупиковой ситуации, требуется тайм-аут принудительной передачи данных, отменяющий алгоритм предотвращения SWS. На практике такой тайм-аут будет возникать редко.

Применимое окно определяется значением

U = SND.UNA + SND.WND - SND.NXT

т. е. предложенное окно меньше объёма переданных, но не подтверждённых данных. Если D – объем ещё не отправленных данных в очереди отправителя на передачу, рекомендуется приведённые ниже правила передачи:

  1. если можно отправить сегмент максимального размера, т. е. min(D,U) >= Eff.snd.MSS;

  2. если данные выталкиваются (push) и можно отправить все данные из очереди, т. е. [SND.NXT = SND.UNA], применяется PUSH и D <= U (выражение в скобках вносит алгоритм Nagle);

  3. если можно отправить хотя бы часть Fs максимального окна передачи, т. е. [SND.NXT = SND.UNA] и min(D,U) >= Fs * Max(SND.WND);

  4. если возникает тайм-аут переопределения.

Здесь Fs – часть, для которой рекомендуемое значение составляет 1/2. Тайм-ауту переопределения следует быть в интервале 0,1 – 1,0 секунда. Может оказаться удобные объединение этого таймера с таймером для нулевого окна (3.8.6.1. Проверка нулевого окна).

3.8.6.2.2. Алгоритм получателя – когда передавать обновление окна

Реализация TCP должна включать алгоритм предотвращения SWS у получателя (MUST-39). Этот алгоритм у получателя определяет, когда можно сдвинуть вправо правый край окна, это обычно называют обновлением окна. Алгоритм сочетается с алгоритмом отложенных подтверждений (параграф 3.8.6.3) для определения, когда сегмент ACK с текущим окном можно действительно передать получателю.

Задачей алгоритма у получателя является предотвращение сдвига правого края окна RCV.NXT+RCV.WND малыми шагами даже при получении данных из сети в мелких сегментах. Предположим, что буфер приёма имеет размер RCV.BUFF. В любой момент RCV.USER октетов из этого общего объёма могут быть связаны с данными, которые приняты и подтверждены, но ещё не считаны пользовательским процессом. При находящемся в покое соединении RCV.WND = RCV.BUFF и RCV.USER = 0.

Сохранение правого края окна неизменным при поступлении и подтверждении данных требует, чтобы получатель предлагал не все своё буферное пространство, т. е. получатель должен указать значение RCV.WND, сохраняющее сумму RCV.NXT+RCV.WND постоянной при увеличении RCV.NXT. Таким образом все буферное пространство RCV.BUFF обычно делится на 3 части, как показано ниже.

    |<------- RCV.BUFF ---------------->|
         1             2            3
----|---------|------------------|------|----
           RCV.NXT               ^
                           (фиксировано)
1 - RCV.USER - полученные, но ещё не подтверждённые данные;
2 - RCV.WND - пространство, анонсируемое отправителю;
3 - Reduction - доступное, но ещё не анонсированное пространство.


Предложенный алгоритм предотвращения SWS для получателя состоит в удержании фиксированной суммы RCV.NXT+RCV.WND, пока не будет выполнено условие

RCV.BUFF - RCV.USER — RCV.WND >= min(Fr * RCV.BUFF, Eff.snd.MSS)

где Fr – часть (рекомендуемое значение 1/2), а Eff.snd.MSS – эффективное значение MSS для соединения (см. параграф 3.7.1. Максимальный размер сегмента (MSS)). При выполнении неравенства устанавливается RCV.WND = RCV.BUFF-RCV.USER.

Отметим, что общий эффект этого алгоритма заключается в увеличении RCV.WND с приращением Eff.snd.MSS (для реалистичных буферов приёма Eff.snd.MSS < RCV.BUFF/2). Отметим также, что получатель должен использовать своё значение Eff.snd.MSS, предполагая, что оно такое же, как у отправителя.

3.8.6.3. Отложенные подтверждения – когда передавать сегмент ACK

Хост, получающий поток сегментов данных TCP, может повысить эффективность сети и участвующих хостов, передавая подтверждения (ACK) не для каждого принятого сегмента. Это называется отложенным подтверждением (delayed ACK).

Конечной точке TCP следует реализовать delayed ACK (SHLD-18), но подтверждения не следует задерживать чрезмерно и задержка должна быть меньше 0,5 сек (MUST-40). ACK следует генерировать не реже, чем для каждого второго полноразмерного сегмента или получения 2*RMSS новых данных (RMSS – значение MSS, заданное конечной точкой TCP, принимающей сегменты, которые будут подтверждаться, или принятое по умолчанию значение MSS) (SHLD-19). Чрезмерная задержка ACK может нарушать синхронизацию приема-передачи и алгоритмы «тактирования» пакетов. Более подробно отложенные подтверждения рассмотрены в параграфе 4.2 RFC 5681 [8], включая рекомендации по незамедлительному подтверждению сегментов с нарушением порядка доставки, сегментов после пропуска в порядковых номерах или внутри пропущенного интервала для ускорения восстановления при потерях.

Отметим, что имеется несколько современных подходов к снижению числа ACK, включая общую разгрузку приёма (generic receive offload или GRO) [72], сжатие и прореживание ACK [28].

3.9. Интерфейсы

Здесь рассматриваются два интерфейса – с пользователем и нижележащим уровнем. Описана достаточно подробно модель интерфейса TCP – пользователь, а интерфейс с модулем протокола нижележащего уровня рассмотрен лишь кратко, поскольку его подробно описывает спецификация нижележащего протокола. Для случая IP отмечены некоторые значения параметров, которые реализации TCP могут использовать.

3.9.1. Интерфейс TCP – пользователь

Приведённые ниже функциональные описания пользовательских команд для реализации TCP являются в лучшем случае вымышленными, поскольку каждая операционная система имеет свои возможности. Поэтому следует предупредить читателей, что в разных реализациях TCP пользовательские интерфейсы могут отличаться. Однако все реализации TCP должны обеспечивать некий минимальный набор услуг, гарантирующий, что все реализации TCP поддерживают общую иерархию протоколов. В этом параграфе рассмотрены функциональные интерфейсы, требуемые в каждой реализации TCP. В параграфе 3.1 [53] указаны предоставляемые TCP примитивы, которые могут служить дополнительным справочником для разработчиков.

В последующих параграфах рассмотрены функциональные характеристики интерфейса TCP – пользователь. Используемые обозначения похожи на применяемые в вызовах процедур и функций в языках высокого уровня, но это не означает исключение вызовов прерываний (ловушек).

Описанные ниже пользовательские команды задают базовые функции, которые реализация TCP должна выполнять для поддержки взаимодействий между процессами. Реализации должны определять свой точный формат и могут обеспечивать комбинации или подмножества базовых функций в одном вызове. В частности, некоторые реализации могут захотеть автоматически создавать (OPEN) соединение при первом вызове пользователем SEND или RECEIVE.

Предоставляя средства межпроцессного взаимодействия, реализация TCP должна не только воспринимать команды, но и возвращать информацию обслуживаемому процессу. Такая информация включает:

  1. общие сведения о соединении (например, прерывания, удалённое закрытие, привязка к неуказанному удалённому сокету);

  2. отклики на конкретные команды пользователя, указывающие успех или соответствующий тип отказа.

3.9.1.1. Open
OPEN (local port, remote socket, active/passive [, timeout] [, Diffserv field] [, security/compartment] 
[, local IP address] [, options]) -> local connection name

Если флаг active/passive установлен для пассивного режима, это будет вызов LISTEN для входящих соединений. Пассивный вызов OPEN может указывать удалённый сокет полностью для восприятия конкретного соединения или не задавать его для восприятия любых соединений. Полностью заданный пассивный вызов можно сделать активным последующим исполнением SEND.

Блок управления передачей (TCB) создаётся и частично заполняется данными из параметров команды OPEN.

Каждый пассивный вызов OPEN создаёт новую запись для соединения в состоянии LISTEN или возвращает ошибку. Таким вызовам недопустимо оказывать влияние на созданные ранее записи соединений (MUST-41).

Поддерживающая одновременные соединения реализация TCP должна обеспечивать вызовы OPEN, функционально позволяющие приложению прослушивать (LISTEN) порт, связанный с локальным портом, находящимся в состоянии SYN-SENT или SYN-RECEIVED (MUST-42).

При активной команде OPEN конечная точка TCP сразу начинает процедуру синхронизации (создания) соединения.

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

Реализация TCP или какая-либо компонента операционной системы (ОС) будет проверять полномочия пользователя на создание соединений с заданным значением поля Diffserv или security/compartment. Отсутствие Diffserv или спецификации security/compartment при вызове OPEN указывает использование принятых по умолчанию значений. TCP будет считать входящие запросы пригодными только при точном соответствии сведений security/compartment заданным при вызове OPEN.

Указанное пользователем значение Diffserv влияет лишь на исходящие пакеты, может быть изменено на пути через сеть и не имеет прямого отношения или влияния на принимаемые пакеты.

Локальное имя соединения реализация TCP возвращает пользователю и оно может служить в качестве краткого обозначения соединения, определяемого парой <локальный сокет, удалённый сокет>.

Необязательный параметр local IP address должен поддерживаться, чтобы можно было указать локальный адрес IP (MUST-43). Это позволяет приложениям выбирать локальный адрес IP на многодомных хостах. Пассивный вызов OPEN с параметром local IP address будет ждать запросы входящих соединений с этим адресом. Если параметр не задан, при пассивном вызове OPEN соединения будут ожидаться на всех адресах с последующей привязкой к использованному в запросе конкретному адресу.

При активном вызове OPEN заданный параметр local IP address будет использован при организации соединения. Если параметр не задан, хост будет выбирать подходящий локальный адрес IP (см. RFC 1122, параграф 3.3.4.2).

Если приложение на многодомном хосте не указывает локальный адрес IP при активном создании соединения TCP, реализация TCP должна запросить у уровня IP выбор локального адреса до отправки (первого) SYN (MUST-44). См. функцию GET_SRCADDR() в параграфе 3.4 RFC 1122.

В остальных случаях для этого соединения уже был принят или передан предыдущий сегмент и реализация TCP должна использовать локальный адрес из прежних сегментов (MUST-45).

Реализация TCP должна отвергать как ошибку локальный вызов OPEN с недействительным удаленным адресом IP (например, групповым или широковещательным) (MUST-46).

3.9.1.2. Send
SEND (local connection name, buffer address, byte count, URGENT flag [, PUSH flag] [, timeout])

Этот вызов ведёт к передаче данных из указанного пользователем буфера в заданное соединение. Если соединение не открыто вызов SEND считается ошибкой. Некоторые реализации могут разрешать пользователю сначала вызывать SEND, автоматически вызывая в этом случае OPEN. Это может быть, например, одним из способов включения данных приложения в сегменты SYN. Если вызывающий процесс не уполномочен использовать указанное соединение, возвращается ошибка.

Конечная точка TCP может реализовать флаг PUSH при вызове SEND (MAY-15). Если этот флаг не реализован, передающей точке TCP (1) недопустимо буферизовать данные на неопределённый срок (MUST-60) и (2) она должна установить бит PSH в последнем буферизованном сегменте (т. е. когда в очереди больше нет данных для передачи) (MUST-61). Далее в описании предполагается поддержка флага PUSH в вызовах SEND.

Если флаг PUSH установлен, приложение считает, что данные будут незамедлительно доставлены получателю, и в последнем сегменте TCP, созданном из буфера, будет установлен флаг PSH. Этот бит не является маркером записи и не зависит от границ сегмента. Передатчику следует при пакетизации данных исключать (collapse) последующие биты для отправки максимально возможного сегмента (SHLD-27).

Если флаг PUSH не установлен, данные могут объединяться с данными из последующих вызовов SEND для более эффективной передачи. Когда приложение делает серию вызовов SEND без установки флага PUSH, реализация TCP может агрегировать данные без их передачи (MAY-16). Отметим, что при использовании алгоритма Nagle реализации TCP могут буферизовать данные до передачи независимо от флага PUSH (см. параграф 3.7.4. Алгоритм Nagle).

Логически прикладная программа требует установки флага PUSH при вызове SEND всякий раз, когда ей нужно форсировать доставку данных, чтобы не возникало блокировки связи. Однако реализации TCP следует по возможности передавать сегменты максимального размера (SHLD-28) для повышения производительности (см. параграф 3.8.6.2.1. Алгоритм отправителя – когда передавать данные).

Новым приложениям не следует устанавливать флаг URGENT flag [39] из-за различий в реализациях и проблем с промежуточными устройствами (SHLD-13). Если флаг URGENT установлен, в сегментах, передаваемых получателю TCP будет задан указатель важности. Принимающий партнёр TCP будет сообщать о важности принимающему процессу, если данные, указатель важности задаёт, что предшествующие ему данные ещё не восприняты принимающим процессом. Целью флага URGENT служит для стимулирования получателя к обработке важных (срочных) данных при их получении. Число сигналов реализации TCP о важности данных не обязано совпадать с числом уведомлений принимающего пользователя о присутствии важных данных.

Если удалённый сокет не был задан при вызове OPEN, но соединение организовано (например, потому, что прослушиваемое соединение организовано в результате прибытия удалённого сегмента в локальный сокет), указанный буфер передаётся в подразумеваемый удалённый сокет. Пользователи, применяющие OPEN без указания удалённого сокета могут вызвать SEND без явного знания адреса этого сокета. Однако, если попытка вызвать SEND предшествует назначению удалённого сокета, возвращается ошибка. Пользователи могут определить статус соединения с помощью вызова STATUS. Некоторые реализации TCP могут уведомлять пользователя о привязке к незаданному сокету.

Если задан параметр timeout, он устанавливает текущий параметр тайм-аута для пользователя соединения.

В простейшей реализации SEND не будет возвращать управление передающему процессу, пока передача не будет завершена или не истечёт время ожидания. Однако в обоих случаях может возникать блокировка (например, обе стороны могут вызвать SEND, не вызвав RECEIVE) и производительность мала, поэтому такие простые решения не рекомендуются. Более изощрённая реализация будет сразу же возвращать управление, чтобы позволить процессу работать одновременно с сетевым вводом-выводом и обеспечить возможность одновременной работы нескольких SEND. Вызовы SEND обслуживаются в порядке поступления, поэтому конечная точка TCP помещает в очередь вызовы, которые она не может обработать сразу же.

Здесь неявно предполагается асинхронный пользовательский интерфейс, через который SEND позднее получает некий сигнал или псевдо-прерывание от обслуживающей конечной точки TCP. Другим вариантом является незамедлительный возврат отклика. Например, SEND может сразу возвращать локальное подтверждение, даже когда сегмент ещё не подтверждён удалённой конечной точкой TCP. Можно оптимистически предположить возможный успех, а при неудаче соединение все равно будет закрыто по тайм-ауту. В реализациях этого типа (синхронных) все равно будут какие-то асинхронные сигналы, но они будут иметь дело с самим соединением, а не с конкретными сегментами или буферами.

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

3.9.1.3. Receive
RECEIVE (local connection name, buffer address, byte count) -> byte count, URGENT flag [, PUSH flag]

Эта команда выделяет приёмный буфер, связанный с указанным соединением. Если перед командой не было вызова OPEN или вызывающему процессу не разрешено использовать это соединение, возвращается ошибка.

В простейшей реализации управление не возвращается вызвавшей программе, пока не будет заполнен буфер или не возникнет ошибка, но эта схема сильно подвержена блокировкам. Более сложная реализация будет разрешать одновременное выполнение нескольких операций RECEIVE, заполняющих буферы по мере поступления сегментов. Такая стратегия позволяет поднять производительность за счёт усложнения схемы (возможно, асинхронной) уведомления вызывающей программы о наличии флага PUSH или заполнении буфера.

Получатель TCP может передать принятый бит PSH прикладному уровню через флаг PUSH на интерфейсе (MAY-17), но это не требуется (см. разъяснения в RFC 1122, параграф 4.2.2.2). Далее в описании вызова RECEIVE предполагается поддержка передачи индикации PUSH.

Если в буфер поступило достаточно данных до того, как был замечен флаг PUSH, этот флаг не устанавливается на интерфейсе в ответ на RECEIVE. В буфер будет помещено столько данных, сколько он может вместить. Если флаг PUSH замечен до заполнения буфера, буфер будет возвращаться заполненным частично с индикацией PUSH.

При наличии важных (срочных) данных пользователь будет проинформирован сразу же по их прибытии через сигнал TCP – пользователь. Принимающему пользователю следует перейти в режим urgent. Если установлен флаг URGENT, это говорит о наличии дополнительных важных данных. Сброшенный флаг URGENT указывает, что этот вызов RECEIVE вернул все важные данные и пользователь может выйти из режима urgent. Отметим, что данные после указателя важности (обычные данные) не могут быть доставлены пользователю в одном буфере с предшествующими важными данными, пока пользователю чётко не указана граница.

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

В реализациях RECEIVE конечная точка TCP может выделять буфер для вызова или использовать кольцевой буфер, созданный для пользователя.

3.9.1.4. Close
CLOSE (local connection name)

Эта команда закрывает указанное соединение. Если соединение не открыто или вызывающий процесс не имеет полномочий использовать соединение, возвращается ошибка. Закрытие соединения должно быть аккуратным в том смысле, что остающиеся вызовы SEND будут обработаны (переданы, включая повторы), насколько позволяет управление потоком данных. Таким образом, следует разрешать несколько вызовов SEND, за которыми следует CLOSE, и ожидать отправки получателю всех данных. Также нужно понимать, что пользователям следует продолжать обработку RECEIVE на закрываемых соединениях, поскольку удалённый партнёр может пытаться передать остаток своих данных. Таким образом, вызов CLOSE означает: «мне нечего больше передать», но не подразумевает: «я больше не принимаю». Может случиться так (если протокол приложения не продуман), что закрывающая сторона не способна справиться со всеми своими данными до возникновения тайм-аута. В таком случае CLOSE превращается в ABORT.

Пользователь может в любой момент вызвать CLOSE по своему усмотрению или по рекомендации (подсказке) реализации TCP (например, закрытие удалённой стороны, тайм-аут, недоступность получателя).

Поскольку для закрытия соединения требуется взаимодействие с удаленным партнёром TCP, процесс закрытия занимает некоторое время. Попытки заново открыть соединение до отклика партнёра TCP на команду CLOSE будут приводить к ошибкам.

Закрытие также предполагает функцию выталкивания (push).

3.9.1.5. Status
STATUS (local connection name) -> status data

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

локальный сокет,
удалённый сокет,
локальное имя соединения,
окно приёма,
окно передачи,
статус соединения,
число буферов, ожидающих подтверждения,
число буферов, ожидающих приёма,
состояние важности (urgent),
значение поля Diffserv,
security/compartment (безопасности, изоляция),
тайм-аут передачи.

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

3.9.1.6. Abort
ABORT (local connection name)

Эта команда вызывает прерывание всех ожидающих SEND и RECEIVE, удаление TCB и передачу специального сообщения RST удалённому партнёру TCP. В зависимости от реализации пользователь может получить индикацию прерывания для каждого остающегося вызова SEND и RECEIVE или просто подтверждение ABORT.

3.9.1.7. Flush

Некоторые реализации TCP включают вызов FLUSH, очищающий очередь передачи TCP от всех данных, которые были включены вызовами SEND, но остаются справа от текущего окна передачи. Т. е. из очереди удаляется как можно больше данных, но без потери синхронизации порядковых номеров. Вызовы FLUSH можно реализовать (MAY-14).

3.9.1.8. Асинхронные отчёты

Должен быть механизм информирования приложения о программных (soft) ошибках TCP (MUST-47). Обычно предполагается, что это предоставляемая приложением процедура ERROR_REPORT которую можно асинхронно вызвать с транспортного уровня

ERROR_REPORT(local connection name, reason, subreason)

Точное кодирование параметров причины (reason и subreason) здесь не задаётся, однако асинхронно сообщаемые приложению условия ошибок должны включать:

  • получение сообщения ICMP об ошибке (см. параграф 3.9.2.2. Сообщения ICMP, где описана обработка каждого типа сообщений ICMP, поскольку для некоторых типов нужно отключать уведомление приложения);

  • избыточные повторы передачи (см. параграф 3.8.3. Отказы соединений TCP);

  • продвижение указателя важности (см. параграф 3.8.5. Обмен важными сведениями).

Прикладной программе, не желающей получать такие вызовы ERROR_REPORT, следует обеспечивать возможность их эффективного отключения (SHLD-20).

3.9.1.9. Установка поля дифференцированного обслуживания (IPv4 TOS или IPv6 Traffic Class)

Уровень приложения должен быть способен установить поле дифференцированного обслуживания (DiffServ) для передаваемых в соединение сегментов (MUST-48). Это поле включает 6 битов кода дифференцированного обслуживания (Differentiated Services Codepoint или DSCP). Это не требуется, но приложению следует поддерживать возможность изменить поле в процессе работы соединения (SHLD-21). Реализациям TCP следует передавать текущее значение поля без изменения на уровень IP при передаче сегментов в соединение (SHLD-22).

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

Реализация TCP может передавать полученное последним значение поля приложению (MAY-9).

3.9.2. Интерфейс TCP – нижележащий уровень

Конечная точка TCP вызывает модуль протокола нижележащего уровня для фактической передачи или приёма данных через сеть. Двумя стандартными версиями протокола Internet (IP), расположенного ниже TCP, в настоящее время являются IPv4 [1] и IPv6 [13].

Если нижележащим протоколом является IPv4, он обеспечивает аргументы для типа обслуживания (указывается в поле DiffServ) и времени жизни (TTL). TCP использует для этих параметров приведённые ниже установки

Diffserv

Значение поля Diffserv в заголовке IP указывает пользователь и оно включает биты кода обслуживания DSCP.

Time to Live (TTL)

Значение TTL для передачи сегментов TCP должно быть настраиваемым (MUST-49).

RFC 793 задаёт 1 минуту (60 секунд) как константу для TTL, поскольку предполагается максимальный срок действия сегмента 2 минуты. Это было предназначено для явного запроса уничтожения сегмента, который не может быть доставлен системой internet в течение 1 минуты. RFC 1122 обновляет RFC 793 требованием настраиваемого поля TTL.

Поле Diffserv может меняться в процессе работы соединения (параграф 4.2.4.2 в RFC 1122), однако интерфейс с приложением может не поддерживать эту возможность и приложение не знает об отдельных сегментах TCP, поэтому в лучшем случае это поле можно установить лишь грубо. Это ограничение рассмотрено в RFC 7657 (параграфы 5.1, 5.3, 6) [50]. Обычно приложению не следует менять поле Diffserv в течение срока действия соединения (SHLD-23).

Любой протокол нижележащего уровня будет предоставлять адреса отправителя и получателя, протокол и способ определения размера TCP для обеспечения функционального эквивалента IP и учёта в контрольной сумме TCP.

При передаче TCP принятых опций от уровня IP, реализация TCP должна игнорировать непонятные опции (MUST-50).

Реализация TCP может поддерживать опции Timestamp (MAY-10) и Record Route (MAY-11).

3.9.2.1. Source Routing

Если нижележащим уровнем является IP (или иной протокол, поддерживающий эту функцию) и применяется маршрутизация от источника (source routing), интерфейс должен обеспечивать обмен маршрутной информацией. Особенно важно, чтобы адреса отправителя и получателя, учитываемые в контрольной сумме TCP, указывали исходного отправителя и окончательного получателя. Важно также сохранение обратного маршрута для ответов на запросы соединения.

Приложение должно быть способно задать source route при активном создании соединения TCP (MUST-51) и этот маршрут должен быть предпочтительней source route, полученного в дейтаграмме (MUST-52).

При пассивном открытии соединения TCP и прибытии пакета с заполненной опцией IP Source Route (содержащей маршрут возврата), реализация TCP должна сохранять обратный маршрут и использовать его для всех сегментов, передаваемых в это соединение (MUST-53). Если позднее в сегменте приходит другой маршрут source route, следует использовать его для замены имеющегося (SHLD-24).

3.9.2.2. Сообщения ICMP

Реализации TCP должны реагировать на сообщения ICMP об ошибках, полученные от уровня IP, направляя их соединению, вызвавшему ошибку (MUST-54). Необходимые для демультиплексирования сведения можно получить из заголовка IP, содержащегося в сообщении ICMP. Это относится к ICMPv6 в дополнение к IPv4 ICMP.

В [35] обсуждаются конкретные сообщения ICMP и ICMPv6, поделенные на мягкие (soft) и жёсткие (hard) ошибки, которые могут вызывать разные отклики. Трактовка сообщений ICMP описана ниже.

Source Quench – притормозить источник

Реализация TCP должна без уведомления отбрасывать любые полученные сообщения ICMP Source Quench (MUST-55). Обсуждение этого вопроса приведено в работе [11].

Мягкие ошибки

Для IPv4 ICMP к таким ошибкам относятся Destination Unreachable с кодами 0, 1, 5, Time Exceeded с кодами 0, 1, Parameter Problem.
Для ICMPv6 это Destination Unreachable с кодами 0, 3, Time Exceeded с 0, 1, Parameter Problem с 0, 1, 2.
Поскольку эти сообщения о недоступности (Unreachable) указывают мягкие ошибки, реализации TCP недопустимо прерывать соединение (MUST-56), а информацию об ошибке следует делать доступной приложению (SHLD-25).

Жёсткие ошибки

Для ICMP к этому относятся Destination Unreachable с кодами 2 – 4.
Это жёсткие ошибки, поэтому реализации TCP следует прерывать соединение (SHLD-26). К [35] отмечено, что некоторые реализации не разрывают соединение при жёсткой ошибке ICMP для соединения, находящегося в каком-либо из синхронизированных состояний.

Отметим, что в разделе 4 [35] описано широко распространённое поведение, при котором мягкие ошибки считаются жёсткими во время организации соединений.

3.9.2.3. Проверка адреса отправителя

RFC 1122 требует проверки адресов во входящих пакетах SYN.

Входящие сегменты SYN с недействительным адресом отправителя должны игнорироваться уровнем TCP или IP [(MUST-63)] (см. параграф 3.2.1.3).

Реализация TCP должна отбрасывать входящие сегменты SYN, направленные по групповому или широковещательному адресу [(MUST-57)].

Это предотвращает ошибочное создание состояний и откликов и разработчикам следует учитывать, что ти рекомендации применимы ко всем входящим сообщениям, а не только к SYN, как указано в RFC 1122.

3.10. Обработка событий

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

Действия конечной точки TCP можно считать откликами на события, которые можно разделить на 3 категории: вызовы пользователя, прибытие сегментов и тайм-ауты. В данном параграфе описывается работа конечной точки TCP для каждого из таких событий. Во многих случаях обработка зависит от текущего состояния. События приведены ниже.

Пользовательские вызовы

OPEN
SEND
RECEIVE
CLOSE
ABORT
STATUS

Прибытие сегментов

прибытие сегмента

Тайм-ауты

пользовательский тайм-аут
таймаут повтора передачи
таймаут TIME-WAIT.

Модель интерфейса TCP – пользователь подразумевает незамедлительный возврат из пользовательских вызовов и возможность отложенных откликов в виде событий или псевдо-прерываний. Далее причина отложенного отклика называется сигналом.

Отклики на ошибки указываются в документе символьными строками, например, команда пользователя для отсутствующего соединения возвращает ошибку error: connection not open.

Следует отметить, что в последующем обсуждении вся арифметимка порядковых номеров, номеров подтверждений, окна и т. п. использует модуль 232 (размер пространства номеров), а знак =< обозначает «меньше или равно» (по модулю 232).

Естественным способом представления обработки входящих сегментов является сначала проверка порядкового номера (т. е. его попадание в пространство номеров окна приёма), затем сегменты обычно помещаются в очередь и обрабатываются в порядке роста номеров.

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

Если смена состояния соединения не указана, предполагается его сохранение.

3.10.1. Вызов OPEN

CLOSED (TCB не существует)

Создаётся новый блок TCB для данных о состоянии соединения с включением идентификатора локального сокета, удалённого сокета, поля Diffserv, security/compartment и пользовательского тайм-аута. Отметим, что удалённый сокет может быть указан не полностью при пассивном вызове OPEN и заполняется параметрами входящего сегмента SYN. Проверяется, что запрошенная защита и Diffserv разрешены для пользователя и в противном случае возвращается error: Diffserv value not allowed или error: security/compartment not allowed. При пассивном вызове соединение переходит в состояние LISTEN с возвратом управления. Если вызов активный и удалённый сокет не задан, возвращается error: remote socket unspecified, а при заданном сокете создаётся сегмент SYN. Выбирается начальный порядковый номер (ISS). Передаётся сегмент SYN вида <SEQ=ISS><CTL=SYN>. Устанавливается SND.UNA = ISS, SND.NXT = ISS+1, соединение переходит в состояние SYN-SENT и управление возвращается.
Если вызывающий не имеет доуступа к указанному локальному сокету, возвращается error: connection illegal for this process, а при отсутствии места для нового соединения – error: insufficient resources.

LISTEN

Если вызов OPEN был активным и удалённый сокет указан, состояние соединения меняется на активное и выбирается ISS. Передаётся сегмент SYN с SND.UNA = ISS, SND.NXT = ISS+1 и соединение переходит в состояние SYN-SENT. Данные, связанные с SEND могут передаваться в сегменте SYN или помещаться в очередь для передачи в состоянии ESTABLISHED. Если команда запрашивает флаг важности, но должен передаваться с сегментом данных как результат этой команды. Если нет места в очереди для запроса, возвращается error: insufficient resources. Если не задан удалённый сокет, возвращается error: remote socket unspecified.

SYN-SENT, SYN-RECEIVED, ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING, LAST-ACK, TIME-WAIT

Возвращается error: connection already exists.

3.10.2. Вызов SEND

CLOSED (TCB не существует)

Если у пользователя нет доступа к соединению, возвращается error: connection illegal for this process, иначе – error: connection does not exist.

LISTEN

Если задан удалённый сокет, соединение переходит в активно состояние и выбирается ISS. Передаётся сегмент SYN с SND.UNA = ISS, SND.NXT = ISS+1 и устанавливается состояние SYN-SENT. Данные, связанные с SEND могут передаваться в сегменте SYN или помещаться в очередь для передачи в состоянии ESTABLISHED. Если команда запрашивает флаг важности, но должен передаваться с сегментом данных как результат этой команды. Если нет места в очереди для запроса, возвращается error: insufficient resources. Если не задан удалённый сокет, возвращается error: remote socket unspecified.

SYN-SENT, SYN-RECEIVED

Данные помещаются в очередь для передачи в состоянии ESTABLISHED. Если нет места в очереди, возвращается error: insufficient resources.

ESTABLISHED, CLOSE-WAIT

Содержимое буфера сегментируется и передаётся с прицепленным подтверждением (RCV.NXT). Если недостаточно пространства для запоминания этого буфера, возвращается error: insufficient resources. При установленном флаге URGENT выполняется SND.UP <- SND.NXT и устанавливается указатель важности в исходящих сегментах.

FIN-WAIT-1, FIN-WAIT-2, CLOSING, LAST-ACK, TIME-WAIT

Возвращается error: connection closing и сервис не запрашивается.

3.10.3. Вызов RECEIVE

CLOSED (TCB не существует)

Если у пользователя нет доступа к соединению, возвращается error: connection illegal for this process, иначе – error: connection does not exist.

LISTEN, SYN-SENT, SYN-RECEIVED

Данные помещаются в очередь для передачи в состоянии ESTABLISHED. Если нет места в очереди, возвращается error: insufficient resources.

ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2

Если число входящих сегментов в очереди недостаточно для выполнения запроса, тот помещается в очередь. Если нет места в очереди, возвращается error: insufficient resources.
Выполняется сборка входящих сегментов из очереди в буфер приёма и управление возвращается пользователю. Если замечен флаг PUSH, устанавливается соответствующий маркер.
Если RCV.UP указывает вперёд передаваемых в данный момент пользователю данных, пользователь уведомляется о наличии важных данных.
Когда конечная точка TCP принимает ответственность за доставку данных пользователю, она должна взаимодействовать с отправителем через подтверждение. Формирование подтверждений описано ниже.

CLOSE-WAIT

Поскольку удалённая сторона уже передала FIN, вызовы RECEIVE должны быть удовлетворены уже полученными данными, которые ещё не доставлены пользователю. Если ожидающих доставки данных нет, RECEIVE возвращает “error: connection closing”, иначе остающиеся данные используются для выполнения RECEIVE.

CLOSING, LAST-ACK, TIME-WAIT

Возвращается error: connection closing.

3.10.4. Вызов CLOSE

CLOSED (TCB не существует)

Если у пользователя нет доступа к соединению, возвращается error: connection illegal for this process, иначе – error: connection does not exist.

LISTEN

Все остающиеся RECEIVE завершаются с error: closing, удаляется TCB, устанавливается состояние CLOSED и возвращается управление.

SYN-SENT

Удаляется TCB и возвращаются отклики error: closing на все находящиеся в очереди запросы SEND и RECEIVE.

SYN-RECEIVED

Если не было вызовов SEND и нет ожидающих передачи данных, формируется и передаётся сегмент FIN, устанавливается состояние FIN-WAIT-1. В иных случаях постановка в очередь для обработки в состоянии ESTABLISHED.

ESTABLISHED

Постановка в очередь всех предшествующих SEND, которые были сегментированы, формирование и передача сегмента FIN, затем переход в состояние FIN-WAIT-1.

FIN-WAIT-1, FIN-WAIT-2

Строго говоря, это ошибка и следует получать отклик error: connection closing. Отклие ok тоже может быть приемлем, если не передан второй сегмент FIN (хотя первый может быть передан повторно).

CLOSE-WAIT

Запрос помещается в очередь, пока все предшествующие SEND не будут сегментированы. Затем передаётся сегмент FIN и устанавливается состояние LAST-ACK.

CLOSING, LAST-ACK, TIME-WAIT

Возвращается error: connection closing.

3.10.5. Вызов ABORT

CLOSED (TCB не существует)

Если у пользователя нет доступа к соединению, возвращается error: connection illegal for this process, иначе – error: connection does not exist.

LISTEN

Всем остающимся вызовам RECEIVE следует возвращать отклие error: connection reset. Удаляется TCB, устанавливается состояние CLOSED и управление возвращается.

SYN-SENT

Всем находящимся в очереди вызовам SEND и RECEIVE следует дать уведомление connection reset. Удаляется TCB, устанавливается состояние CLOSED и управление возвращается.

SYN-RECEIVED, ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT

Передаётся сегмент сброса <SEQ=SND.NXT><CTL=RST>.
Всем находящимся в очереди вызовам SEND и RECEIVE следует дать уведомление connection reset. Все сегменты, помещённые в очередь на передачу (кроме указанного выше RST) или повтор передачи следует очистить. Удаляется TCB, устанавливается состояние CLOSED и управление возвращается.

CLOSING, LAST-ACK, TIME-WAIT

Возвращается отклие ok, удаляется TCB, устанавливается состояние CLOSED и управление возвращается.

3.10.6. Вызов STATUS

CLOSED (TCB не существует)

Если у пользователя нет доступа к соединению, возвращается error: connection illegal for this process, иначе – error: connection does not exist.

LISTEN

Возврат state = LISTEN и указателя TCB.

SYN-SENT

Возврат state = SYN-SENT и указателя TCB.

SYN-RECEIVED

Возврат state = SYN-RECEIVED и указателя TCB.

ESTABLISHED

Возврат state = ESTABLISHED и указателя TCB.

FIN-WAIT-1

Возврат state = FIN-WAIT-1 и указателя TCB.

FIN-WAIT-2

Возврат state = FIN-WAIT-2 и указателя TCB.

CLOSE-WAIT

Возврат state = CLOSE-WAIT и указателя TCB.

CLOSING

Возврат state = CLOSING и указателя TCB.

LAST-ACK

Возврат state = LAST-ACK и указателя TCB.

TIME-WAIT

Возврат state = TIME-WAIT и указателя TCB.

3.10.7. Прибытие сегмента

3.10.7.1. Состояние CLOSED

В состоянии CLOSED (TCB не существует) все данные входящего сегмента отбрасываются. Сегмент с RST отбрасывается, а входящий сегмент без RST вызывает передачу RST в ответ. Выбираются значения полей подтверждения и порядкового номера, чтобы сделать последовательность сброса приемлемой для конечной точки TCP, отправившей проблемный сегмент.

Если бит ACK сброшен (0), используется порядковый номер 0 – <SEQ=0><ACK=SEG.SEQ+SEG.LEN><CTL=RST,ACK>. При установленном (1) бите ACK передаётся <SEQ=SEG.ACK><CTL=RST>. Управление возвращается.

3.10.7.2. Состояние LISTEN
  1. Проверка наличия бита RST.

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

  2. Проверка наличия бита ACK.

    Любое подтверждение, прибывшее с состоянии LISTEN, является недействительным. В ответ следует передать подходящий сегмент сброса <SEQ=SEG.ACK><CTL=RST>. Возврат управления.

  3. Проверка наличия бита SYN.

    При установленном флаге SYN проверяются установки безопасности и если security/compartment во входящем сегменте не совпадает с security/compartment в TCB передаётся сброс и управление возвращается <SEQ=0><ACK=SEG.SEQ+SEG.LEN><CTL=RST,ACK>.

    Устанавливается RCV.NXT = SEG.SEQ+1, IRS = SEG.SEQ, все остальные элементы управления и данные следует поместить в очередь для последующей обработки. Следует выбрать значение ISS и передать сегмент SYN вида <SEQ=ISS><ACK=RCV.NXT><CTL=SYN,ACK>.

    Устанавливается SND.NXT = ISS+1, SND.UNA = ISS. Состояние соединения меняется на SYN-RECEIVED. Отметим, что другие элементы управления и данные (в комбинации с SYN) будут обрабатываться в состоянии SYN-RECEIVED, но обработку SYN и ACK повторять не следует. Если вызов LISTEN был задан не полностью (удалённый сокет не указан целиком), следует заполнить не заданные поля.

  4. Проверка других элементов управления и данных.

    Этого не должно происходить. Сегмент отбрасывается и возвращается управление. Любой другой сегмент с элементами управления или данными (без SYN) должен иметь поле ACK и, таким образом, будет отброшен при проверке ACK на этапе 2, если не будет отброшен на этапе 1 при проверке RST.

3.10.7.3. Состояние SYN-SENT
  1. Проверка наличия бита ACK.

    При установленном бите ACK выполняются указанные ниже проверки.

    • Если SEG.ACK =< ISS или SEG.ACK > SND.NXT, передаётся сброс (если нет флага RST, при котором сегмент отбрасывается с возвратом управления) <SEQ=SEG.ACK><CTL=RST> и сегмент отбрасывается с возвратом управления.

    • Если SND.UNA < SEG.ACK =< SND.NXT, проверяется пригодность ACK. Некоторые реализации TCP используют проверку SEG.ACK == SND.NXT (== вместо =<), но это не применимо, когда стек может передавать данные по SYN, так как партнёр TCP не может воспринять и подтвердить все данные по SYN.

  1. Проверка наличия бита RST.

    При установленном бите RST выполняются указанные ниже проверки.

    • Возможная атака со сбросом вслепую описана в RFC 5961 [9]. Описанное в этом документе смягчение имеет описанную в нем конкретную применимость и не является заменой криптографической защиты (например, IPsec или TCP-AO). Реализации TCP с поддержкой описанного в RFC 5961 смягчения следует сначала проверить точное совпадение порядкового номера значению RCV.NXT и лишь потом выполнять действия следующего абзаца.

    • Если ACK был приемлем, пользователю передаётся error: connection reset, сегмент отбрасывается, устанавливается состояние CLOSED с удалением TCB и возвратом управления. В ином случае (нет ACK) сегмент просто отбрасывается с возвратом управления.

  1. Проверяются установки безопасности.

    Если security/compartment в сегменте не совпадает с security/compartment в TCB, передаётся сброс:

    • При наличии в сегменте ACK передаётся <SEQ=SEG.ACK><CTL=RST>, в противном случае – <SEQ=0><ACK=SEG.SEQ+SEG.LEN><CTL=RST,ACK>.

Если передан сброс, сегмент отбрасывается с возвратом управления.

  1. Проверка наличия бита SYN.

    Этого не должно происходить при корректно ACK или его отсутствии в сегменте без RST.

    Если бит SYN установлен и параметры security/compartment приемлемы, устанавливается RCV.NXT = SEG.SEQ+1, IRS = SEG.SEQ. Значению SND.UNA следует быть не меньше SEG.ACK (если это ACK) и все сегменты из очереди повторной передачи, подтверждённые таким путём, должны быть удалены.

    Если SND.UNA > ISS (SYN был подтверждён), соединение переходит в состояние ESTABLISHED, формируется и передаётся сегмент ACK <SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK>, в который можно включить данные и элементы управления из очереди. Некоторые реализации TCP подавляют передачу этого сегмента, когда принятый сегмент содержит данные, которые в любом случае создают подтверждение на последующих этапах обработки. Если в сегменте есть другие элементы управления или данные, обработка продолжается с п. 6 в параграфе 3.10.7.4, где проверяется бит URG. В ином случае управление возвращается.

    В противном случае устанавливается состояние SYN-RECEIVED, формируется и передаётся сегмент SYN,ACK <SEQ=ISS><ACK=RCV.NXT><CTL=SYN,ACK>. Устанавливаются переменные

    SND.WND <- SEG.WND
    SND.WL1 <- SEG.SEQ
    SND.WL2 <- SEG.ACK

    Если в сегменте есть другие элементы управления или данные, они помещаются в очередь для обработки в состоянии ESTABLISHED и управление возвращается.

    Отметим допустимость передачи и приёма данных приложения в сегментах SYN, как отмечено выше. Исторически сложились существенные искажения и неверная интерпретация этого. Некоторые межсетевые экраны и устройства защиты считают такие сегменты подозрительными. Однако эта возможность была использована в T/TCP [21] и применяется в TCP Fast Open (TFO) [48], поэтому важна её поддержка в реализациях и сетевых устройствах.

  2. Если биты SYN и RST не установлены, сегмент отбрасывается с возвратом управления.

3.10.7.4. Другие состояния

Первым делом проверяется порядковый номер.

SYN-RECEIVED, ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING, LAST-ACK, TIME-WAIT

  • Сегменты обрабатываются по порядку. Первые проверки по прибытии служат для отбрасывания старых дубликатов, а дополнительные проверки выполняются в порядке SEG.SEQ. Если содержимое сегмента пересекает границу между старой и новой частью, обрабатывается только новая.

  • В общем случае обработка принятых сегментов должна быть реализована для агрегирования сегментов ACK, когда это возможно (MUST-58). Например, если конечная точка TCP обрабатывает последовательность сегментов из очереди, все они должны быть обработаны до отправки какого-либо ACK (MUST-59).

  • Имеется 4 случая для проверки пригодности входыщих сегментов, показанные в таблице 6.

Таблица 6. Проверка пригодности сегмента.

 

Размер сегмента

Окно приема

Проверка

0
0
 SEG.SEQ = RCV.NXT
0
>0
 RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND
>0
0
 not acceptable
>0
>0
 RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND
или
 RCV.NXT =< SEG.SEQ+SEG.LEN-1 < RCV.NXT+RCV.WND

 

  • При реализации описанной здесь проверки порядковых номеров следует учитывать Приложение A.2. Проверка порядковых номеров.

  • Если RCV.WND = 0, сегменты не будут приемлемы, но следует воспринимать действительные ACK, URG, RST.

  • Если входящий сегмент неприемлем, следует передать в ответ подтверждение (если не установлен флаг RST, когда сегмент отбрасывается с возвратом управления) вида <SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK>. После передачи подтверждения неприемлемый сегмент отбрасывается с возвратом управления.

  • Отметим, что для состояния TIME-WAIT в [40] представлен улучшенный алгоритм обработки входящих сегментов SYN с использованием временных меток вместо описанной здесь проверки порядковых номеров. При реализации такого алгоритма описанная выше логика не применяется для входящих сегментов SYN с опцией Timestamp, принятых в состоянии TIME-WAIT.

  • Далее сегменты считаются идеализированными, начинающимися с RCV.NXT и не выходящими за пределы окна. Фактические сегменты можно привести к этому допущению, отрезав выходящие за пределы окна части (включая SYN и FIN) и обрабатывая лишь оставшееся, как будто сегмент начинается с RCV.NXT. Сегменты, начинающиеся с больших порядковых номеров следует оставлять для последующей обработки (SHLD-31).

Вторым этапом служит проверка бита RST.

В разделе 3 RFC 5961 [9] описана возможная атака со сбросом вслепую и предложения по смягчению. Это не обеспечивает криптографической защиты *например, как IPsec или TCP-AO), но применимо в случае RFC 5961. Для стеков, реализующих описанную в RFC 5961 защиту, применимы три проверки, указанных ниже. В остальных случаях проверки выполняются в зависимости от состояния, как описано далее.

    1. При установленном бите RST и порядковым номером вне текущего окна приёма сегмент отбрасывается.

    2. Если бит RST установлен и порядковый номер точно соответствует ожидаемому (RCV.NXT), конечная точка TCP должна сбросит соединение, как описано ниже для соответствующего состояния.

    3. Если бит RST установлен и порядковый номер не соответствует ожидаемому, но попадает в текущее окно приёма, конечная точка TCP должна передать подтверждение (challenge ACK) <SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK>.

      После отправки challenge ACK конечные точки TCP должны отбрасывать неприемлемые сегменты и останавливать дальнейшую обработку входящих пакетов. Отметим, что в RFC 5961 и Errata ID 4772 [99] приведены дополнительные соображения по contain дросселированию (throttling) ACK в реализации.

SYN-RECEIVED

При установленном бите RST.
  • Если соединение инициировано пассивным вызовом OPEN (т. е. перешло из состояния LISTEN), оно возвращается в состояние LISTEN и управление возвращается вызвавшему процессу без необходимости информировать пользователя. Если вызов OPEN был активным (т. е. переход из состояния SYN-SENT), соединение отвергается с передачей пользователю ошибки connection refused. Соединение переходит в состояние CLOSED с удалением TCB и возвратом управления.
    В любом случае очередь повторной передачи следует очистить.

ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT

Если бит RST установлен, оставшимся вызовам RECEIVE и SEND следует получить отклики reset с очисткой всех сегментов из очереди. Пользователю следует получить незапрошенный общий сигнал connection reset. Соединение переходит в состояние CLOSED с удалением TCB и возвратом управления.

CLOSING, LAST-ACK, TIME-WAIT

Если бит RST установлен, соединение переходит в состояние CLOSED с удалением TCB и возвратом управления.

На третьем этапе проверяется безопасность.

SYN-RECEIVED

Если security/compartment в сегменте не соответствует точно security/compartment в TCB, передаётся сброс и управление возвращается.

ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING, LAST-ACK, TIME-WAIT

  • Если security/compartment в сегменте не соответствует точно security/compartment в TCB, передаётся сброс, оставшимся вызовам RECEIVE и SEND следует получить отклики reset с очисткой всех сегментов из очереди. Пользователю следует получить незапрошенный общий сигнал connection reset. Соединение переходит в состояние CLOSED с удалением TCB и возвратом управления.

  • Отметим, что эта проверка выполняется вслед за проверкой порядкового номера, чтобы предотвратить прерывание сегмента старым сегментом между теми же номерами портов с другим уровнем безопасности, вызывающего прерывание текущего соединения.

На четвёртом этапе проверяется бит SYN.

SYN-RECEIVED

  • Если соединение инициировано пассивным вызовом OPEN, оно переходит в состояние LISTEN с возвратом управления. В ином случае выполняется обработка в соответствии с синхронизированными состояниями.

ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING, LAST-ACK, TIME-WAIT

  • Если установлен бит SYN, это может быть легитимная попытка нового соединения (например, для TIME-WAIT), ошибка, при которой нужно сбросить соединение или результат попытки атаки, как описано в RFC 5961 [9]. Для TIME-WAIT новое соединение может быть воспринято, если применяется опция Timestamp и метка соответствует ожиданиям (в соответствии с [40]). Для других случаев RFC 5961 предоставляет смягчение атаки, применимое в некоторых ситуациях, но имеются также варианты криптографической защиты (см. 7. Вопросы безопасности и приватности). В соответствии с рекомендациями RFC 5961 для этих синхронизированных состояний при установленном флаге SYN независимо от порядкового номера конечная точка TCP должна передать удалённому партнёру challenge ACK <SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK>.
  • После отправки подтверждения реализация TCP должна отбросить неприемлемый сегмент и прекратить обработку. Отметим, что в RFC 5961 и Errata ID 4772 [99] приведены дополнительные замечанию по дросселированию ACK для реализации.
  • Для реализаций, не следующих RFC 5961, применяется поведение, описанное в RFC 793. Если SYN попадает в окно, это является ошибкой – передаётся сброс, остающимся RECEIVE и SEND следует получить отклик reset, все сегменты из очереди следует очистить, а пользователю следует передать незапрошенный сигнал connection reset. Соединение переводится в состояние CLOSED с удалением TCB и возвратом управления. Если SYN не попадает в окно, до этого этапа дело не доходит и сегмент ACK передаётся на первом этапе проверки порядкового номера.

Пятым этапом является проверка поля ACK.

  • Если бит ACK сброшен (0) сегмент отбрасывается с возвратом управления.
  • Если бит ACK установлен (1),выполняются указанные ниже действия.
    • В разделе 5 RFC 5961 [9] описаны возможные атаки с внедрением вслепую и смягчение этих атак, которое можно включить в реализацию (MAY-12). Стеки TCP, реализующие RFC 5961, должны добавлять входную проверку приемлемости значения ACK, если оно находится в диапазоне (SND.UNA – MAX.SND.WND) =< SEG.ACK =< SND.NXT. Все входящие сегменты, не удовлетворяющие этому условию, должны отбрасываться с передачей ACK. Новое состояние переменной MAX.SND.WND определяется наибольшим значением размера окна, полученного локальным отправителем от его партнёра (может изменяться) или может быть жёстко закодировано максимально допустимым размером окна. Когда значение ACK приемлемо, выполняются указанные ниже проверки в зависимости от состояния.

SYN-RECEIVED

  • Если SND.UNA < SEG.ACK =< SND.NXT, соединение переходит в состояние ESTABLISHED и продолжается обработка с установкой значений
    SND.WND <- SEG.WND
    SND.WL1 <- SEG.SEQ
    SND.WL2 <- SEG.ACK
  • Если подтверждение сегмента не приемлемо, формируется и передаётся сегмент сброса <SEQ=SEG.ACK><CTL=RST>.

ESTABLISHED

  • Если SND.UNA < SEG.ACK =< SND.NXT, устанавливается SND.UNA <- SEG.ACK. Все подтверждённый таким образом сегменты из очереди повторной передачи удаляются. Пользователям следует отправить позитивные подтверждения для буферов, которые переданы (SENT) и полностью подтверждены (т. е. буфер SEND вернул отклик ok). Если ACK является дубликатом (SEG.ACK =< SND.UNA), его можно игнорировать. Если ACK подтверждает ещё не переданное (SEG.ACK > SND.NXT), передаётся ACK и сегмент отбрасывается с возвратом управления.
  • Если SND.UNA =< SEG.ACK =< SND.NXT, следует обновить окно передачи. Если (SND.WL1 < SEG.SEQ или (SND.WL1 = SEG.SEQ и SND.WL2 =< SEG.ACK)), устанавливается SND.WND <- SEG.WND, SND.WL1 <- SEG.SEQ, SND.WL2 <- SEG.ACK. Отметим, что SND.WND – это смещение от SND.UNA, SND.WL1 содержит порядковый номер последнего сегмента, использованного для обновления SND.WND, а SND.WL2 – номер подтверждения последнего сегмента, использованного для обновления SND.WND. Эта проверка предотвращает использование старых сегментов для обновления окна.

FIN-WAIT-1

В дополнение к обработке для состояния ESTABLISHED, если сегмент FIN подтверждён, состояние меняется на FIN-WAIT-2 и продолжается обработка там.

FIN-WAIT-2

В дополнение к обработке для состояния ESTABLISHED, если очередь передачи пуста, пользовательский вызов CLOSE можно подтвердить (ok), но без удаления TCB.

CLOSE-WAIT

Та же обработка, что и для состояния ESTABLISHED.

CLOSING

В дополнение к обработке для состояния ESTABLISHED, если ACK подтверждает наш FIN, сообщение переходит в состояние TIME-WAIT, в противном случае сегмент игнорируется.

LAST-ACK

В этом состоянии может приходить лишь подтверждение нашего FIN. Если сегмент FIN подтверждён, удаляется TCB, соединение переходит в состоянии CLOSED и возвращается управление.

TIME-WAIT

В этом состоянии может приходить лишь подтверждение нашего FIN, которое подтверждается и выполняется перезапуск с тайм-аутом 2 MSL.

Шестым этапом является проверка бита URG.

ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2

При установленном бите URG устанавливается RCV.UP <- max(RCV.UP,SEG.UP) и пользователю подаётся сигнал о наличии важных данных, если указатель важности (RCV.UP) указывает дальше (вперёд) воспринятых данных. Если пользователь уже уведомлен (или находится в режиме urgent) об этой непрерывной последовательности важных данных, новое уведомление не передается.

CLOSE-WAIT, CLOSING, LAST-ACK, TIME-WAIT

Этого не должно быть, поскольку от удалённой стороны уже получен сегмент FIN. Флаг URG игнорируется.

Седьмым этаком является обработка данных (текста).

ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2

  • В состоянии ESTABLISHED можно доставлять сегмент данных в пользовательский буфер RECEIVE. Данные из сегментов можно перемещать в буферы до их заполнения или до завершения сегмента. Если сегмент использован полностью (пуст) и содержит флаг PUSH, пользователь информируется о получении PUSH.
  • Когда конечная точка TCP принимает на себя ответственность за доставку данных пользователю, она должна подтвердить получение данных.
  • Как только конечная точка TCP приняла ответственность за данные, она продвигает RCV.NXT за полученные данные и корректирует RCV.WND должным образом в соответствии с текущей доступностью буфера. Сумму RCV.NXT и RCV.WND не следует снижать.
  • Реализация TCP может передать сегмент ACK, подтверждающий RCV.NXT, когда прибывает пригодный сегмент, попадающий в окно, но не находящийся на левом краю окна (MAY-13).
  • Отметим предложения по управлению окном из параграфа 3.8. Обмен данными.
  • Передаётся сегмент подтверждения в форме <SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK>. Это подтверждение следует цеплять (piggyback) к сегменту, который будет передаваться, по возможности, без неоправданной задержки.

CLOSE-WAIT, CLOSING, LAST-ACK, TIME-WAIT

Этого не может быть, поскольку от удалённой стороны получен сегмент FIN. Данные из сегмента игнорируются.

На восьмом этапе проверяется бит FIN.

  • В состоянии CLOSED, LISTEN или SYN-SENT бит FIN не обрабатывается, поскольку нет возможности проверить SEG.SEQ. Сегмент отбрасывается с возвратом управления.

  • Если бит FIN установлен, пользователю передаётся сигнал connection closing, возвращаются все ожидающие RECEIVE с тем же сообщение, значение RCV.NXT продвигается на FIN и передаётся подтверждение FIN. Отметим, что FIN предполагает PUSH для любых данных сегмента, ещё не доставленных пользователю.

SYN-RECEIVED, ESTABLISHED

Переход в состояние CLOSE-WAIT.

FIN-WAIT-1

Если наш сегмент FIN был подтверждён (возможно, в этом сегменте), соединение переходит в состояние TIME-WAIT, запускается таймер ожидания с отключением других таймеров. В ином случае переход в состояние CLOSING.

FIN-WAIT-2

Переход в состояние TIME-WAIT. Запуск таймера ожидания с отключением других таймеров.

CLOSE-WAIT

Сохраняется состояние CLOSE-WAIT.

CLOSING

Сохраняется состояние CLOSING.

LAST-ACK

Сохраняется состояние LAST-ACK.

TIME-WAIT

Сохраняется состояние TIME-WAIT и перезапускается таймер ожидания 2 MSL.

Далее управление возвращается вызвавшему процессу.

3.10.8. Тайм-ауты

USER TIMEOUT

По завершении отсчёта пользовательского таймера в любом состоянии очищаются все очереди, пользователю обычно передаётся error: connection aborted due to user timeout, удаляется TCB и соединение переходит в состояние CLOSED с возвратом управления.

RETRANSMISSION TIMEOUT

По завершению отсчёта таймера повторной передачи для сегмента из очереди в любом состоянии повторно передаётся сегмент из начала очереди, таймер запускается снова и управление возвращается.

TIME-WAIT TIMEOUT

По тайм-ауту ожидания (time-wait) в соединении удаляется TCB и соединение переходит в состояние CLOSED с возвратом управления.

4. Глоссарий

ACK – подтверждение

Бит управления (acknowledge) подтверждение, на занимающий пространства порядковых номеров, который указывает, что поле Acknowledgment в этом сегменте указывает следующий порядковый номер, который отправитель этого сегмента ждёт получить, тем самым подтверждая все предыдущие номера.

Connection – соединение

Логический коммуникационный путь, определяемый парой сокетов.

Datagram – дейтаграмма

Сообщение, переданное в компьютерной коммуникационной сети с коммутацией пакетов.

Destination Address – адрес получателя

Адрес сетевого уровня конечной точки, для которой предназначен сегмент.

FIN – завершение

Бит управления (финиш), занимающий 1 порядковый номер и указывающий, что отправитель больше не будет передавать данные или элементы управления, занимающие пространство номеров.

Flush – очистка

Удаление всего содержимого (данные или сегменты) из хранилища (буфер или очередь).

Fragment – фрагмент

Часть логического блока данных. Например, фрагмент internet является частью дейтаграммы internet.

Header – заголовок

Управляющая информация в начале сообщения, сегмента, фрагмента, пакета или блока данных.

Host – хост

Компьютер. В частности, это источник или получатель сообщений с точки зрения коммуникационной сети.

Identification – идентификация

Поле протокола IP, указываемое отправителем и помогающее при сборке фрагментов.

internet address – адрес internet

Адрес сетевого уровня.

internet datagram – дейтаграмма internet

Блок данных, передаваемых между хостами internet вместе с заголовком internet так, чтобы дейтаграмму можно было маршрутизировать от источника к получателю.

internet fragment – фрагмент internet

Часть дейтаграммы internet с заголовком internet.

IP

Протокол Internet, см. [1] и [13].

IRS

Начальный порядковый номер приёма – первый номер, использованный отправителем в соединении.

ISN

Начальный порядковый номер – первый номер, используемый в соединении (ISS или IRS). Выбирается так, чтобы быть уникальным в данный период времени и непредсказуемым для злоумышленников.

ISS

Начальный порядковый номер приёма – первый номер, используемый отправителем в соединении.

left sequence – левый край

Следующий порядковый номер, который должен быть подтверждён принимающей данные стороной TCP (или наименьший ещё не подтверждённый номер), иногда его называют левым краем окна передачи.

Module – модуль

Реализация (обычно программная) протокола или иной процедуры.

MSL (Maximum Segment Lifetime)

Максимальное время жизни сегмента – время, в течение которого сегмент TCP может существовать в межсетевой системе (internetwork). Сейчас выбрано произвольное значение 2 минуты.

Octet – октет

8-битовый байт.

Options – опции

Поле Option может включать несколько опций, каждая из которых может занимать несколько октетов.

Packet – пакет

Пакет данных с заголовком, который может быть логически полным или неполным. Пакетирование данных чаще бывает физическим, чем логическим.

Port – порт

Часть идентификатора соединения, служащая для демультиплексирования соединений в конечной точке.

Process – процесс

Исполняемая программа. Источник или получатель данных с точки зрения конечной точки TCP или иного протокола «хост-хост».

PUSH – выталкивание

Бит управления, не занимающий пространство порядковых номеров и указывающий, что сегмент содержит данные, которые должны быть «вытолкнуты» принимающему пользователю.

RCV.NXT

Следующий номер на приёме.

RCV.UP

Принятый указатель важности.

RCV.WND

Окно приёма.

receive next sequence number

Следующий порядковый номер, который локальная конечная точка TCP ожидает получить.

receive window – окно приёма

Представляет порядковые номера, которые локальная (принимающая) конечная точка TCP готова получить. Таким образом, конечная точка TCP считает, что сегменты из диапазона от RCV.NXT до RCV.NXT + RCV.WND – 1 содержат приемлемые данные или управление. Сегменты, содержащие порядковые номера полностью за пределами этого диапазона, считаются дубликатами или вставками при атаке и отбрасываются.

RST

Бит управления (сброс), не занимающий пространства порядковых номеров и указывающий, что получателю следует удалить соединение без дальнейшего взаимодействия. Получатель на основе порядкового номера и поля подтверждения во входящем сегменте может определить, нужно выполнить команду сброса или игнорировать её. Получение сегмента RST никогда не ведёт к отправке ответного RST.

SEG.ACK

Подтверждение сегмента.

SEG.LEN

Размер сегмента.

SEG.SEQ

Порядковый номер сегмента.

SEG.UP

Поле указателя важности в сегменте.

SEG.WND

Поле окна в сегменте.

Segment – сегмент

Логический блок данных. В частности, сегмент данных TCP является блоком данных, передаваемых между парой модулей TCP.

segment acknowledgment – подтверждение сегмента

Порядковый номер в поле подтверждения прибывающего сегмента.

segment length – размер сегмента

Количество порядковый номеров, занятых сегментом, включая элементы управления с номерами.

segment sequence – порядковый номер сегмента

Значение поля порядкового номера в прибывающем сегменте.

send sequence

Следующий порядковый номер, который локальная (передающая) конечная точка TCP будет использовать в соединении. Первоначально номер выбирается из кривой исходных порядковых номеров (ISN), а затем инкрементируется для каждого передаваемого октета данных или элемента управления.

send window – окно передачи

Представляет порядковые номера, которые удалённая (принимающая) конечная точка TCP готова принять. Это значение поля окна в сегментах от удалённой (принимающей данные) конечной точки TCP. Диапазон новых порядковых номеров, которые могут быть переданы реализацией TCP находится между SND.NXT и SND.UNA + SND.WND – 1 (естественно, предполагается возможность повторной передачи из диапазона SND.UNA – SND.NXT).

SND.NXT

Номер для передачи.

SND.UNA

Порядковый номер слева (окна).

SND.UP

Указатель важности для передачи.

SND.WL1

Порядковый номер сегмента при последнем обновлении окна.

SND.WL2

Номер подтверждения при последнем обновлении окна.

SND.WND

Окно передачи.

socket (socket number, socket address, socket identifier) – сокет (номер, идентификатор, адрес сокета)

Адрес, включающий номер порта, т. е. конкатенация адреса Internet (IP) и порта TCP.

Source Address

Адрес канального уровня передающей конечной точки.

SYN

Бит управления во входящем сегменте, занимающий 1 порядковый номер и служащий для инициирования соединения путём указания начального порядкового номера.

TCB

Блок управления передачей – структура данных, содержащая состояние соединения.

TCP

Протокол управления передачей – протокол коммуникаций между хостами для надёжного взаимодействия в межсетевых средах.

TOS

Тип обслуживания – устаревшее поле IPv4. Эти биты заголовка в настоящее время применяются для поля дифференцированных услуг (Differentiated Services) [4], содержащего код дифференцированного обслуживания (Differentiated Services Codepoint или DSCP) и 2-битовый код ECN [6].

Type of Service – тип обслуживания

См. TOS.

URG

Бит управления (urgent), не занимающий пространства номеров и служащий для указания принимающему партнёру необходимости уведомить пользователя о необходимости срочной обработки, пока есть данные с номерами меньше, чем значение указателя важности.

urgent pointer – указатель важности

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

5. Отличия от RFC 793

Этот документ отменяет RFC 793, а также обновляющие его RFC 6093 и RFC 6528. Во всех случаях в документ были включены лишь нормативная спецификация и требования, а информационный текст с обоснованиями не переносился. Информационная часть отменённых документов сохраняет интерес для изучения и понимания TCP, несмотря на перенос нормативных частей в этот документ.

Основная часть этого документа адаптирована из раздела 3 в RFC 793 (Функциональная спецификация) с попыткой максимального сохранения форматирования и макета.

В документе учтены сведения об ошибках (RFC errata), принятые или отложенные до обновления RFC 793 (Errata ID: 573 [73], 574 [74], 700 [75], 701 [76], 1283 [77], 1561 [78], 1562 [79], 1564 [80], 1571 [81], 1572 [82], 2297 [83], 2298 [84], 2748 [85], 2749 [86], 2934 [87], 3213 [88], 3300 [89], 3301 [90], 6222 [91]). Некоторые сообщения не были включены, поскольку их учли в других изменениях (Errata ID: 572 [92], 575 [93], 1565 [94], 1569 [95], 2296 [96], 3305 [97], 3602 [98]).

Внесены изменения спецификации указателя важности (срочности), описанные в RFC 1011, RFC 1122, RFC 6093. Подробное обсуждение необходимости этих изменений представлено в RFC 6093.

Обсуждение RTO в RFC 793 было обновлено ссылкой на RFC 6298. Связанный с RTO текст RFC 1122 в своё время заменил текст RFC 793, однако позднее RFC 2988 обновил RFC 1122, а сам был потом отменён RFC 6298.

В RFC 1011 [18] содержится много комментариев к RFC 793, включая некоторые изменения спецификации TCP. Они были расширены в RFC 1122, где содержится набор изменений и разъяснений к RFC 793. Влияющие на протокол нормативные элементы включены в этот документ, хотя часть исторически полезных советов по реализации и обсуждений из RFC 1122 не была включена. Настоящий документ, который сейчас является спецификацией TCP вместо RFC 793, обновляет RFC 1011 и комментарии из RFC 1011 включены здесь.

В RFC 1122 содержатся не просто требования к TCP, поэтому данный документ не может отменить RFC 1122 целиком. Он лишь обновляет RFC 1122, однако следует понимать, что это фактически отменяет все относящиеся к TCP сведения в RFC 1122.

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

Добавлено основанное на RFC 6429 примечание для явного разъяснение того, что управление ресурсами системы позволяет высвобождать ресурсы соединения. RFC 6429 отменён в том смысле, что это разъяснение отражено в этой базовой спецификации.

Добавлено описание реализации контроля перегрузок на основе документов IETF BCP и Standards Track, соответствующих задачам и текущему состоянию распространённых реализаций.

6. Взаимодействие с IANA

В реестр Transmission Control Protocol (TCP) Header Flags агентство IANA внесло описанные здесь изменения.

В RFC 3168 был исходно создан этот реестр с указанием лишь заданных в RFC 3168 битов без учёта битов, описанных ранее в RFC 793 и других документах. После этого бит 7 был обновлён в RFC 8311 [54].

Столбец Bit был переименован в Bit Offset (Смещение), поскольку он указывает смещение каждого флага заголовка в 16 битовом слове заголовка TCP на рисунке 1. Биты со смещением 0-3 являются полем TCP Data Offset, а не флагами.

Агентство IANA добавило столбец Assignment Notes (замечанию к назначению).

Выделенные IANA значения представлены в таблице 7.

Таблица 7. Флаги заголовков TCP.

Смещение

Имя

Документ

Замечания к назначению

4

Резерв на будущее

RFC 9293

5

Резерв на будущее

RFC 9293

6

Резерв на будущее

RFC 9293

7

Резерв на будущее

RFC 8311

Ранее применялся RFC 3540 как NS (Nonce Sum).

8

CWR (Congestion Window Reduced)

RFC 3168

9

ECE (ECN-Echo)

RFC 3168

10

Поле Urgent pointer значимо (URG)

RFC 9293

11

Поле Acknowledgment значимо (ACK)

RFC 9293

12

Функция Push (PSH)

RFC 9293

13

Сброс соединения (RST)

RFC 9293

14

Синхронизация порядковых номеров (SYN)

RFC 9293

15

У отправителя больше нет данных (FIN)

RFC 9293

Реестр TCP Header Flags перенесён в субреестр реестра Transmission Control Protocol (TCP) Parameters <https://www.iana.org/assignments/tcp-parameters/>. Процедурой регистрации для реестра остаётся Standards Action, но ссылка (Reference) обновлена с указанием данного документа, а колонка Note удалена.

7. Вопросы безопасности и приватности

TCP включает лишь рудиментарные свойства защиты, повышающие отказоустойчивость и надёжность соединений и доставки данных приложений, но не имеет криптографических средств поддержки проверки подлинности, защиты конфиденциальности и других функций защиты. Были разработаны некриптографические улучшения (например, [9]) для повышения устойчивости соединений TCP к отдельным типам атак, но применимость и защита некриптографических средств ограничены (см., например, параграф 1.1 в [9]). Приложения обычно применяют протокол нижележащего (например, IPsec) и вышележащего (например, TLS) уровня для обеспечения защиты и приватности соединений TCP и передаваемых по ним данных приложений. Были разработаны и методы на основе опций TCP для поддержки некоторых защитных возможностей.

Для полного обеспечения конфиденциальности, защиты целостности и аутентификации соединений TCP (включая флаги управления) единственным методом сейчас является IPsec. Доступна защита целостности и контроль подлинности с помощью опции TCP Authentication (TCP-AO) [38], а предложенное расширение обеспечивает конфиденциальность содержимого сегментов. Другие методы, описанные здесь, могут обеспечить конфиденциальность или целостность для содержимого, но включают лишь часть полей заголовка (например, tcpcrypt [57]) или не защищают их совсем (например, TLS). Другие средства защиты, добавленные в TCP (например, генерация ISN, проверка порядковых номеров и пр.) способны лишь частично отражать атаки.

Приложения с длительными потоками TCP были уязвимы для атак, использующих обработку флагов управления, описанную в ранних спецификациях TCP[33]. Опция TCP-MD5 широко реализована для поддержки аутентификации некоторых из этих соединений, но имеет недостатки и признана устаревшей. TCP-AO обеспечивает возможность защиты длительных соединений TCP от атак и превосходит по своим свойствам TCP-MD5. Однако она на защищает приватность данных приложений и заголовков TCP.

Экспериментальное расширение tcpcrypt [57] обеспечивает возможность криптографической защиты данных соединения. Аспекты метаданных потока по-прежнему видны, но поток приложения хорошо защищён. В заголовке TCP обеспечивается лишь защита указателя важности и флага FIN.

TCP Roadmap [49] включает замечания о нескольких RFC, связанных с безопасностью TCP. В этом документе объединены многие из предложенных в этих RFC улучшений, включая генерацию ISN, смягчение атак вслепую в окне, улучшение обработки мягких ошибок и пакетов ICMP. Все это подробно рассматривается в упомянутых RFC, исходно описывающих изменения, требуемые в ранних спецификациях TCP. В RFC 6093 [39] рассмотрены вопросы безопасности, относящиеся к полю указателя важности, а также рекомендуется не применять его в новых реализациях.

Поскольку TCP часто применяется для передачи больших объёмов данных, возможны атаки, злоупотребляющие логикой управления контролем перегрузок, например, атаки ACK-division. В спецификации механизмов контроля перегрузок TCP были внесены изменения для смягчения таких атак, например, подходящий поток байтов (Appropriate Byte Counting или ABC) [29].

Другие атаки нацелены на истощение ресурсов сервера TCP. Примеры включают лавинные атаки SYN [32] или расход ресурсов на неактивные соединения [41]. Операционные системы реализуют смягчение таких атак. В число распространённых средств защиты входят прокси, межсетевые экраны с учётом состояния и другие методы за пределами реализации TCP на конечном хосте.

Концепция образа протокола в линии (wire image), описанная в RFC 8546 [56], указывает, как открытые заголовки TCP раскрывают узлам на пути больше метаданных, нежели нужно для маршрутизации пакетов адресатам. Злоумышленники на пути могут использовать такие метаданные. Извлечённые из этого уроки для TCP были применены при разработке нового транспорта, такого как QUIC [60]. Кроме того, имеются соображения, частично основанные на опыте работы с TCP и расширениями протокола, которые можно применить при разработке новых транспортных расширения TCP и иного транспорта, опубликованные IETF в RFC 9065 [61], наряду с рекомендациями IAB в RFC 8558 [58] и [67].

Существуют также методы отпечатков (fingerprinting), которые можно применять для извлечения версии реализации TCP на хосте (в ОС) или сведений о платформе. Они собирают наблюдения по нескольким аспектам, таким как опции в сегментах, их порядок, специфическое поведение в разных условиях, синхронизация пакетов и другие аспекты протокола, оставленные для задания разработчикам, и могут по этим сведениям определять хост и реализацию.

Поскольку обработка сообщений ICMP также может взаимодействовать с соединениями TCP, имеются возможные атаки на основе ICMP. Они рассмотрены в RFC 5927 [100] вместе с реализованными мерами по смягчению.

8. Литература

8.1. Нормативные документы

[1] Postel, J., “Internet Protocol”, STD 5, RFC 791, DOI 10.17487/RFC0791, September 1981, <https://www.rfc-editor.org/info/rfc791>.

[2] Mogul, J. and S. Deering, “Path MTU discovery”, RFC 1191, DOI 10.17487/RFC1191, November 1990, <https://www.rfc-editor.org/info/rfc1191>.

[3] Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels”, BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, <https://www.rfc-editor.org/info/rfc2119>.

[4] Nichols, K., Blake, S., Baker, F., and D. Black, “Definition of the Differentiated Services Field (DS Field) in the IPv4 and IPv6 Headers”, RFC 2474, DOI 10.17487/RFC2474, December 1998, <https://www.rfc-editor.org/info/rfc2474>.

[5] Floyd, S., “Congestion Control Principles”, BCP 41, RFC 2914, DOI 10.17487/RFC2914, September 2000, <https://www.rfc-editor.org/info/rfc2914>.

[6] Ramakrishnan, K., Floyd, S., and D. Black, “The Addition of Explicit Congestion Notification (ECN) to IP”, RFC 3168, DOI 10.17487/RFC3168, September 2001, <https://www.rfc-editor.org/info/rfc3168>.

[7] Floyd, S. and M. Allman, “Specifying New Congestion Control Algorithms”, BCP 133, RFC 5033, DOI 10.17487/RFC5033, August 2007, <https://www.rfc-editor.org/info/rfc5033>.

[8] Allman, M., Paxson, V., and E. Blanton, “TCP Congestion Control”, RFC 5681, DOI 10.17487/RFC5681, September 2009, <https://www.rfc-editor.org/info/rfc5681>.

[9] Ramaiah, A., Stewart, R., and M. Dalal, “Improving TCP’s Robustness to Blind In-Window Attacks”, RFC 5961, DOI 10.17487/RFC5961, August 2010, <https://www.rfc-editor.org/info/rfc5961>.

[10] Paxson, V., Allman, M., Chu, J., and M. Sargent, “Computing TCP’s Retransmission Timer”, RFC 6298, DOI 10.17487/RFC6298, June 2011, <https://www.rfc-editor.org/info/rfc6298>.

[11] Gont, F., “Deprecation of ICMP Source Quench Messages”, RFC 6633, DOI 10.17487/RFC6633, May 2012, <https://www.rfc-editor.org/info/rfc6633>.

[12] Leiba, B., “Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words”, BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, <https://www.rfc-editor.org/info/rfc8174>.

[13] Deering, S. and R. Hinden, “Internet Protocol, Version 6 (IPv6) Specification”, STD 86, RFC 8200, DOI 10.17487/RFC8200, July 2017, <https://www.rfc-editor.org/info/rfc8200>.

[14] McCann, J., Deering, S., Mogul, J., and R. Hinden, Ed., “Path MTU Discovery for IP version 6”, STD 87, RFC 8201, DOI 10.17487/RFC8201, July 2017, <https://www.rfc-editor.org/info/rfc8201>.

[15] Allman, M., “Requirements for Time-Based Loss Detection”, BCP 233, RFC 8961, DOI 10.17487/RFC8961, November 2020, <https://www.rfc-editor.org/info/rfc8961>.

8.2. Дополнительная литература

[16] Postel, J., “Transmission Control Protocol”, STD 7, RFC 793, DOI 10.17487/RFC0793, September 1981, <https://www.rfc-editor.org/info/rfc793>.

[17] Nagle, J., “Congestion Control in IP/TCP Internetworks”, RFC 896, DOI 10.17487/RFC0896, January 1984, <https://www.rfc-editor.org/info/rfc896>.

[18] Reynolds, J. and J. Postel, “Official Internet protocols”, RFC 1011, DOI 10.17487/RFC1011, May 1987, <https://www.rfc-editor.org/info/rfc1011>.

[19] Braden, R., Ed., “Requirements for Internet Hosts – Communication Layers”, STD 3, RFC 1122, DOI 10.17487/RFC1122, October 1989, <https://www.rfc-editor.org/info/rfc1122>.

[20] Almquist, P., “Type of Service in the Internet Protocol Suite”, RFC 1349, DOI 10.17487/RFC1349, July 1992, <https://www.rfc-editor.org/info/rfc1349>.

[21] Braden, R., “T/TCP — TCP Extensions for Transactions Functional Specification”, RFC 1644, DOI 10.17487/RFC1644, July 1994, <https://www.rfc-editor.org/info/rfc1644>.

[22] Mathis, M., Mahdavi, J., Floyd, S., and A. Romanow, “TCP Selective Acknowledgment Options”, RFC 2018, DOI 10.17487/RFC2018, October 1996, <https://www.rfc-editor.org/info/rfc2018>.

[23] Paxson, V., Allman, M., Dawson, S., Fenner, W., Griner, J., Heavens, I., Lahey, K., Semke, J., and B. Volz, “Known TCP Implementation Problems”, RFC 2525, DOI 10.17487/RFC2525, March 1999, <https://www.rfc-editor.org/info/rfc2525>.

[24] Borman, D., Deering, S., and R. Hinden, “IPv6 Jumbograms”, RFC 2675, DOI 10.17487/RFC2675, August 1999, <https://www.rfc-editor.org/info/rfc2675>.

[25] Xiao, X., Hannan, A., Paxson, V., and E. Crabbe, “TCP Processing of the IPv4 Precedence Field”, RFC 2873, DOI 10.17487/RFC2873, June 2000, <https://www.rfc-editor.org/info/rfc2873>.

[26] Floyd, S., Mahdavi, J., Mathis, M., and M. Podolsky, “An Extension to the Selective Acknowledgement (SACK) Option for TCP”, RFC 2883, DOI 10.17487/RFC2883, July 2000, <https://www.rfc-editor.org/info/rfc2883>.

[27] Lahey, K., “TCP Problems with Path MTU Discovery”, RFC 2923, DOI 10.17487/RFC2923, September 2000, <https://www.rfc-editor.org/info/rfc2923>.

[28] Balakrishnan, H., Padmanabhan, V., Fairhurst, G., and M. Sooriyabandara, “TCP Performance Implications of Network Path Asymmetry”, BCP 69, RFC 3449, DOI 10.17487/RFC3449, December 2002, <https://www.rfc-editor.org/info/rfc3449>.

[29] Allman, M., “TCP Congestion Control with Appropriate Byte Counting (ABC)”, RFC 3465, DOI 10.17487/RFC3465, February 2003, <https://www.rfc-editor.org/info/rfc3465>.

[30] Fenner, B., “Experimental Values In IPv4, IPv6, ICMPv4, ICMPv6, UDP, and TCP Headers”, RFC 4727, DOI 10.17487/RFC4727, November 2006, <https://www.rfc-editor.org/info/rfc4727>.

[31] Mathis, M. and J. Heffner, “Packetization Layer Path MTU Discovery”, RFC 4821, DOI 10.17487/RFC4821, March 2007, <https://www.rfc-editor.org/info/rfc4821>.

[32] Eddy, W., “TCP SYN Flooding Attacks and Common Mitigations”, RFC 4987, DOI 10.17487/RFC4987, August 2007, <https://www.rfc-editor.org/info/rfc4987>.

[33] Touch, J., “Defending TCP Against Spoofing Attacks”, RFC 4953, DOI 10.17487/RFC4953, July 2007, <https://www.rfc-editor.org/info/rfc4953>.

[34] Culley, P., Elzur, U., Recio, R., Bailey, S., and J. Carrier, “Marker PDU Aligned Framing for TCP Specification”, RFC 5044, DOI 10.17487/RFC5044, October 2007, <https://www.rfc-editor.org/info/rfc5044>.

[35] Gont, F., “TCP’s Reaction to Soft Errors”, RFC 5461, DOI 10.17487/RFC5461, February 2009, <https://www.rfc-editor.org/info/rfc5461>.

[36] StJohns, M., Atkinson, R., and G. Thomas, “Common Architecture Label IPv6 Security Option (CALIPSO)”, RFC 5570, DOI 10.17487/RFC5570, July 2009, <https://www.rfc-editor.org/info/rfc5570>.

[37] Sandlund, K., Pelletier, G., and L-E. Jonsson, “The Robust Header Compression (ROHC) Framework”, RFC 5795, DOI 10.17487/RFC5795, March 2010, <https://www.rfc-editor.org/info/rfc5795>.

[38] Touch, J., Mankin, A., and R. Bonica, “The TCP Authentication Option”, RFC 5925, DOI 10.17487/RFC5925, June 2010, <https://www.rfc-editor.org/info/rfc5925>.

[39] Gont, F. and A. Yourtchenko, “On the Implementation of the TCP Urgent Mechanism”, RFC 6093, DOI 10.17487/RFC6093, January 2011, <https://www.rfc-editor.org/info/rfc6093>.

[40] Gont, F., “Reducing the TIME-WAIT State Using TCP Timestamps”, BCP 159, RFC 6191, DOI 10.17487/RFC6191, April 2011, <https://www.rfc-editor.org/info/rfc6191>.

[41] Bashyam, M., Jethanandani, M., and A. Ramaiah, “TCP Sender Clarification for Persist Condition”, RFC 6429, DOI 10.17487/RFC6429, December 2011, <https://www.rfc-editor.org/info/rfc6429>.

[42] Gont, F. and S. Bellovin, “Defending against Sequence Number Attacks”, RFC 6528, DOI 10.17487/RFC6528, February 2012, <https://www.rfc-editor.org/info/rfc6528>.

[43] Borman, D., “TCP Options and Maximum Segment Size (MSS)”, RFC 6691, DOI 10.17487/RFC6691, July 2012, <https://www.rfc-editor.org/info/rfc6691>.

[44] Touch, J., “Updated Specification of the IPv4 ID Field”, RFC 6864, DOI 10.17487/RFC6864, February 2013, <https://www.rfc-editor.org/info/rfc6864>.

[45] Touch, J., “Shared Use of Experimental TCP Options”, RFC 6994, DOI 10.17487/RFC6994, August 2013, <https://www.rfc-editor.org/info/rfc6994>.

[46] McPherson, D., Oran, D., Thaler, D., and E. Osterweil, “Architectural Considerations of IP Anycast”, RFC 7094, DOI 10.17487/RFC7094, January 2014, <https://www.rfc-editor.org/info/rfc7094>.

[47] Borman, D., Braden, B., Jacobson, V., and R. Scheffenegger, Ed., “TCP Extensions for High Performance”, RFC 7323, DOI 10.17487/RFC7323, September 2014, <https://www.rfc-editor.org/info/rfc7323>.

[48] Cheng, Y., Chu, J., Radhakrishnan, S., and A. Jain, “TCP Fast Open”, RFC 7413, DOI 10.17487/RFC7413, December 2014, <https://www.rfc-editor.org/info/rfc7413>.

[49] Duke, M., Braden, R., Eddy, W., Blanton, E., and A. Zimmermann, “A Roadmap for Transmission Control Protocol (TCP) Specification Documents”, RFC 7414, DOI 10.17487/RFC7414, February 2015, <https://www.rfc-editor.org/info/rfc7414>.

[50] Black, D., Ed. and P. Jones, “Differentiated Services (Diffserv) and Real-Time Communication”, RFC 7657, DOI 10.17487/RFC7657, November 2015, <https://www.rfc-editor.org/info/rfc7657>.

[51] Fairhurst, G. and M. Welzl, “The Benefits of Using Explicit Congestion Notification (ECN)”, RFC 8087, DOI 10.17487/RFC8087, March 2017, <https://www.rfc-editor.org/info/rfc8087>.

[52] Fairhurst, G., Ed., Trammell, B., Ed., and M. Kuehlewind, Ed., “Services Provided by IETF Transport Protocols and Congestion Control Mechanisms”, RFC 8095, DOI 10.17487/RFC8095, March 2017, <https://www.rfc-editor.org/info/rfc8095>.

[53] Welzl, M., Tuexen, M., and N. Khademi, “On the Usage of Transport Features Provided by IETF Transport Protocols”, RFC 8303, DOI 10.17487/RFC8303, February 2018, <https://www.rfc-editor.org/info/rfc8303>.

[54] Black, D., “Relaxing Restrictions on Explicit Congestion Notification (ECN) Experimentation”, RFC 8311, DOI 10.17487/RFC8311, January 2018, <https://www.rfc-editor.org/info/rfc8311>.

[55] Chown, T., Loughney, J., and T. Winters, “IPv6 Node Requirements”, BCP 220, RFC 8504, DOI 10.17487/RFC8504, January 2019, <https://www.rfc-editor.org/info/rfc8504>.

[56] Trammell, B. and M. Kuehlewind, “The Wire Image of a Network Protocol”, RFC 8546, DOI 10.17487/RFC8546, April 2019, <https://www.rfc-editor.org/info/rfc8546>.

[57] Bittau, A., Giffin, D., Handley, M., Mazieres, D., Slack, Q., and E. Smith, “Cryptographic Protection of TCP Streams (tcpcrypt)”, RFC 8548, DOI 10.17487/RFC8548, May 2019, <https://www.rfc-editor.org/info/rfc8548>.

[58] Hardie, T., Ed., “Transport Protocol Path Signals”, RFC 8558, DOI 10.17487/RFC8558, April 2019, <https://www.rfc-editor.org/info/rfc8558>.

[59] Ford, A., Raiciu, C., Handley, M., Bonaventure, O., and C. Paasch, “TCP Extensions for Multipath Operation with Multiple Addresses”, RFC 8684, DOI 10.17487/RFC8684, March 2020, <https://www.rfc-editor.org/info/rfc8684>.

[60] Iyengar, J., Ed. and M. Thomson, Ed., “QUIC: A UDP-Based Multiplexed and Secure Transport”, RFC 9000, DOI 10.17487/RFC9000, May 2021, <https://www.rfc-editor.org/info/rfc9000>.

[61] Fairhurst, G. and C. Perkins, “Considerations around Transport Header Confidentiality, Network Operations, and the Evolution of Internet Transport Protocols”, RFC 9065, DOI 10.17487/RFC9065, July 2021, <https://www.rfc-editor.org/info/rfc9065>.

[62] IANA, “Transmission Control Protocol (TCP) Parameters”, <https://www.iana.org/assignments/tcp-parameters/>.

[63] Gont, F., “Processing of IP Security/Compartment and Precedence Information by TCP”, Work in Progress, Internet-Draft, draft-gont-tcpm-tcp-seccomp-prec-00, 29 March 2012, <https://datatracker.ietf.org/doc/html/draft-gont-tcpm-tcp-seccomp-prec-00>.

[64] Gont, F. and D. Borman, “On the Validation of TCP Sequence Numbers”, Work in Progress, Internet-Draft, draft-gont-tcpm-tcp-seq-validation-04, 11 March 2019, <https://datatracker.ietf.org/doc/html/draft-gont-tcpm-tcp-seq-validation-04>.

[65] Touch, J. and W. M. Eddy, “TCP Extended Data Offset Option”, Work in Progress, Internet-Draft, draft-ietf-tcpm-tcp-edo-12, 15 April 2022, <https://datatracker.ietf.org/doc/html/draft-ietf-tcpm-tcp-edo-12>.

[66] McQuistin, S., Band, V., Jacob, D., and C. Perkins, “Describing Protocol Data Units with Augmented Packet Header Diagrams”, Work in Progress, Internet-Draft, draft-mcquistin-augmented-ascii-diagrams-10, 7 March 2022, <https://datatracker.ietf.org/doc/html/draft-mcquistin-augmented-ascii-diagrams-10>.

[67] Thomson, M. and T. Pauly, “Long-Term Viability of Protocol Extension Mechanisms”, RFC 9170, DOI 10.17487/RFC9170, December 2021, <https://www.rfc-editor.org/info/rfc9170>.

[68] Minshall, G., “A Suggested Modification to Nagle’s Algorithm”, Work in Progress, Internet-Draft, draft-minshall-nagle-01, 18 June 1999, <https://datatracker.ietf.org/doc/html/draft-minshall-nagle-01>.

[69] Dalal, Y. and C. Sunshine, “Connection Management in Transport Protocols”, Computer Networks, Vol. 2, No. 6, pp. 454-473, DOI 10.1016/0376-5075(78)90053-3, December 1978, <https://doi.org/10.1016/0376-5075(78)90053-3>.

[70] Faber, T., Touch, J., and W. Yui, “The TIME-WAIT state in TCP and Its Effect on Busy Servers”, Proceedings of IEEE INFOCOM, pp. 1573-1583, DOI 10.1109/INFCOM.1999.752180, March 1999, <https://doi.org/10.1109/INFCOM.1999.752180>.

[71] Postel, J., “Comments on Action Items from the January Meeting”, IEN 177, March 1981, <https://www.rfc-editor.org/ien/ien177.txt>.

[72] “Segmentation Offloads”, The Linux Kernel Documentation, <https://www.kernel.org/doc/html/latest/networking/segmentation-offloads.html>.

[73] RFC Errata, Erratum ID 573, RFC 793, <https://www.rfc-editor.org/errata/eid573>.

[74] RFC Errata, Erratum ID 574, RFC 793, <https://www.rfc-editor.org/errata/eid574>.

[75] RFC Errata, Erratum ID 700, RFC 793, <https://www.rfc-editor.org/errata/eid700>.

[76] RFC Errata, Erratum ID 701, RFC 793, <https://www.rfc-editor.org/errata/eid701>.

[77] RFC Errata, Erratum ID 1283, RFC 793, <https://www.rfc-editor.org/errata/eid1283>.

[78] RFC Errata, Erratum ID 1561, RFC 793, <https://www.rfc-editor.org/errata/eid1561>.

[79] RFC Errata, Erratum ID 1562, RFC 793, <https://www.rfc-editor.org/errata/eid1562>.

[80] RFC Errata, Erratum ID 1564, RFC 793, <https://www.rfc-editor.org/errata/eid1564>.

[81] RFC Errata, Erratum ID 1571, RFC 793, <https://www.rfc-editor.org/errata/eid1571>.

[82] RFC Errata, Erratum ID 1572, RFC 793, <https://www.rfc-editor.org/errata/eid1572>.

[83] RFC Errata, Erratum ID 2297, RFC 793, <https://www.rfc-editor.org/errata/eid2297>.

[84] RFC Errata, Erratum ID 2298, RFC 793, <https://www.rfc-editor.org/errata/eid2298>.

[85] RFC Errata, Erratum ID 2748, RFC 793, <https://www.rfc-editor.org/errata/eid2748>.

[86] RFC Errata, Erratum ID 2749, RFC 793, <https://www.rfc-editor.org/errata/eid2749>.

[87] RFC Errata, Erratum ID 2934, RFC 793, <https://www.rfc-editor.org/errata/eid2934>.

[88] RFC Errata, Erratum ID 3213, RFC 793, <https://www.rfc-editor.org/errata/eid3213>.

[89] RFC Errata, Erratum ID 3300, RFC 793, <https://www.rfc-editor.org/errata/eid3300>.

[90] RFC Errata, Erratum ID 3301, RFC 793, <https://www.rfc-editor.org/errata/eid3301>.

[91] RFC Errata, Erratum ID 6222, RFC 793, <https://www.rfc-editor.org/errata/eid6222>.

[92] RFC Errata, Erratum ID 572, RFC 793, <https://www.rfc-editor.org/errata/eid572>.

[93] RFC Errata, Erratum ID 575, RFC 793, <https://www.rfc-editor.org/errata/eid575>.

[94] RFC Errata, Erratum ID 1565, RFC 793, <https://www.rfc-editor.org/errata/eid1565>.

[95] RFC Errata, Erratum ID 1569, RFC 793, <https://www.rfc-editor.org/errata/eid1569>.

[96] RFC Errata, Erratum ID 2296, RFC 793, <https://www.rfc-editor.org/errata/eid2296>.

[97] RFC Errata, Erratum ID 3305, RFC 793, <https://www.rfc-editor.org/errata/eid3305>.

[98] RFC Errata, Erratum ID 3602, RFC 793, <https://www.rfc-editor.org/errata/eid3602>.

[99] RFC Errata, Erratum ID 4772, RFC 5961, <https://www.rfc-editor.org/errata/eid4772>.

[100] Gont, F., “ICMP Attacks against TCP”, RFC 5927, DOI 10.17487/RFC5927, July 2010, <https://www.rfc-editor.org/info/rfc5927>.

Приложение A. Замечания по реализации

В этом приложении приведены дополнительные примечания и ссылки на решения по реализации TCP, которые в настоящее время не включены в RFC и не являются частью стандарта TCP. Эти элементы могли быть рассмотрены разработчиками, но ещё не включены в стандарт.

A.1. IP Security Compartment и Precedence

Спецификация IPv4 [1] включает значение предпочтений в ныне отмененное поле типа обслуживания (Type of Service или TOS). Оно было изменено в [20], а сейчас отменено определением дифференцированного обслуживания (Differentiated Services или Diffserv) [4]. установка и передача поля TOS между сетевым уровнем, реализацией TCP и приложениями устарела и заменена Diffserv в текущей спецификации TCP.

RFC 793 требует проверки изоляции и предпочтений безопасности IP во входящих сегментах TCP на предмет согласованности с соединением и запросами приложений. Каждый из этих аспектов IP устарел, но в RFC 793 не внесено соответствующих обновлений. Проблема с предпочтениями решена в [25] со статусом Standards Track, поэтому действующая спецификация TCP включает эти изменения. Однако состояние опций безопасности IP, которые могут применяться в многоуровневых системах защиты (Multi-Level Secure или MLS) не столь очевидно в IETF.

Сброс соединений при несоответствии входящий пакетов ожиданиям в части изоляции или предпочтений был сочтён возможным вектором атак [63] и обсуждались поправки к спецификации TCP для предотвращения разрыва соединений из-за несоответствия изоляции безопасности IP и кодов Diffserv.

A.1.1. Предпочтение

В Diffserv прежнее значение precedence, считается кодом селектора класса (Class Selector) и совместимые методы обработки описаны в архитектуре Diffserv. Спецификация TCP,заданная в RFC 793 и RFC 1122 включает логику, предназначенную для использования приложением наивысшего уровня предпочтения или сохранения предпочтений, согласованных для соединения. Эта логика для устаревших TOS не применима к Diffserv и её не следует включать в реализации TCP, хотя смена значений Diffserv в рамках соединения не рекомендуется. Обсуждение этих вопросов приведено в RFC 7657 (параграфы 5.1, 5.3, 6) [50].

Устаревшие правила обработки TOS в TCP предполагали двухсторонние (симметричные) значения предпочтений в соединении, а архитектура Diffserv асимметрична. Проблемы прежней логики TCP в этой части описаны в [25] и предложено игнорировать IP precedence в TCP. Поскольку RFC 2873 задаёт стандарт (Standards Track), хотя и не указывает обновление RFC 793, предполагается устойчивость текущих реализаций к этим условиям. Отметим, что применяемое для каждого направления значение поля Diffserv является частью интерфейса между TCP и сетевым уровнем, а значения могут быть заданы между TCP и приложением в обоих направлениях.

A.1.2. Системы MLS

Опция IP Security (IPSO) и изоляция, определённые в [1], пересмотрены в RFC 1038, который был отменен RFC 1108. Опция Commercial IP Security (CIPSO) определена в FIPS-188 (отозван NIST в 2015 г.) и поддерживается некоторыми производителями и операционными системами. RFC 1108 сейчас считается устаревшим (Historic), хотя RFC 791 не был обновлён с удалением опции IP Security. Для IPv6 похожая опция (Common Architecture Label IPv6 Security Option или CALIPSO) определена в [36]. RFC 793 включает логику, применяющую сведения security/compartment при трактовке сегментов TCP. Упоминания IP security/compartment в этом документе могут иметь отношение к разработкам систем многоуровневой защиты, но могут не приниматься во внимание системами, не включающими MLS, с работающим в Internet кодом (см. A.1. IP Security Compartment и Precedence). Отметим, что в RFC 5570 описаны некоторые межсетевые системы MLS, где может применяться IPSO, CIPSO или CALIPSO. В этих особых случаях разработчикам TCP следует ознакомиться с параграфом 7.3.1 RFC 5570 и выполнять рекомендации этого документа.

A.2. Проверка порядковых номеров

В некоторых случаях правила проверки порядковых номеров TCP могут препятствовать обработке полей ACK. Это может приводить к проблемам соединений, описанным в [64], где рассмотрены проблемы, возможные при одновременной организации соединений, самоподключении, одновременном закрытии и одновременном зондировании окна. В документе также описаны возможные изменения спецификации TCP для смягчения проблемы путём расширения приемлемых порядковых номеров.

При использовании TCP в Internet эти условия возникают редко, Основные операционные системы включают различные дополнительные варианты смягчения, а стандарт ещё не обновлён с учётом этого, но разработчикам следует учитывать проблемы, описанные в [64].

A.3. Изменение алгоритма Nagle

В распространённых ОС алгоритм Nagle и отложенные подтверждения реализованы и по умолчанию включены. TCP применяется во многих приложениях «запрос-отклик», где сочетание алгоритма Nagle с отложенными подтверждениями может снижать производительность приложения. В работе [68] описано изменение алгоритма Nagle , решающего эту проблему. Это изменение реализовано в основных ОС и не влияет на совместимость TCP. Кроме того, многие приложения просто отключают алгоритм Nagle, поскольку он обычно поддерживается опцией сокета. Стандарт TCP не изменён в части включения этой модификации алгоритма Nagle, но разработчики могут счесть её полезной.

A.4. Настройки Low Watermark

Некоторые реализации TCP в ядре ОС включают опции сокета, позволяющие задать число байтов в буфере, пока уровень сокета передаёт отправляемые данные TCP (SO_SNDLOWAT) или принятые – приложению (SO_RCVLOWAT).

Кроме того, опция сокета TCP_NOTSENT_LOWAT может применяться для управления число не переданных байтов в очереди записи. Это может помочь передающему приложению TCP избежать создания большого объёма буферизованных данных (м соответствующей задержки). Например, это может быть полезно для приложений, мультиплексирующих данные из нескольких потоков вышележащего уровня в одно соединение, особенно при чередовании в потоков интерактивных (реальный масштаб времени) обменов и передачи больших объёмов.

Приложение B. Сводка требований TCP

Это приложение является адаптацией RFC 1122.

Отметим, что требования, связанные с PLPMTUD в таблице не приведены, но реализация PLPMTUD рекомендуется.

Таблица 8. Сводка требований TCP.

Свойство

ReqID

MUST

SHOULD

MAY

SHOULD NOT

MUST NOT

Флаг PUSH

Агрегирование или размещение в очереди невыталкиваемых данных

MAY-16

X

Отправитель исключает последовательные биты PSH

SHLD-27

X

Вызов SEND может включать флаг PUSH

MAY-15

X

  • при невозможности буферизация на неопределённый срок

MUST-60

X

  • при невозможности устанавливать бит PSH в последнем сегменте

MUST-61

X

Уведомление принимающего ALP3 о флаге PSH

MAY-17

X

Передача сегмента максимального размера, когда это возможно

SHLD-28

X

Размер окна

Трактовка значения как целого числа без знака

MUST-1

X



Обработка как 32-битового числа

REC-1

X



Сокращение окна справа

SHLD-14

X


  • передача новых данных при сокращении окна

SHLD-15

X


  • повторная передача не подтверждённых данных из окна

SHLD-16

X


  • тайм-аут соединения для данных после правого края

SHLD-17

X


Устойчивость к сокращению окна

MUST-34

X


Закрытие приёмного окна на неопределённый срок

MAY-8

X


Использование стандартной логики зондирования

MUST-35

X


Зондирование нулевого окна отправителем

MUST-36

X


  • первое зондирование после интервала RTO

SHLD-29

X


  • экспоненциальное снижение частоты проб

SHLD-30

X


Разрешение нулевого окна в неопределённый срок

MUST-37

X


Повтор старых данных сверх SND.UNA+SND.WND

MAY-7

X


Обработка RST и URG даже при нулевом окне

MUST-66

X


Важные данные

Наличие поддержки для указателя важности (urgent)

MUST-30

X


Указатель задаёт первый октет после важных данных

MUST-62

X


Произвольный размер последовательности важных данных

MUST-31

X


Асинхронное информирование ALP о поступлении важных данных

MUST-32

X


ALP может узнать, как много важных данных нужно прочесть

MUST-33

X


Реализация механизма важности (срочности) в ALP

SHLD-13

X


Опции TCP

Поддержка обязательных опций

MUST-4

X


Приём опций TCP в любом сегменте

MUST-5

X


Игнорирование не поддерживаемых опций

MUST-6

X


Включение размера во все опции, кроме EOL+NOP

MUST-68

X


Устойчивость к опциям некорректного размера

MUST-7

X


Обработка опций, не выравненных по границе слова

MUST-64

X


Приём и передача опции MSS

MUST-14

X


IPv4 передаёт опцию MSS пока не 536

SHLD-5

X


IPv6 передаёт опцию MSS пока не 1220

SHLD-5

X


Всегда передавать опцию MSS

MAY-3

X


IPv4 Send-MSS по умолчанию 536

MUST-15

X


IPv6 Send-MSS по умолчанию 1220

MUST-15

X


Расчёт эффективного размера передаваемого сегмента

MUST-16

X


MSS учитывает изменение MTU

SHLD-6

X


MSS не передаётся в сегментах без флага SYN

MUST-65

Значение MSS на основе MMS_R

MUST-67

X

Заполнение нулями

MUST-69

X

Контрольная сумма TCP

Расчёт контрольной суммы отправителем

MUST-2

X

Проверка контрольной суммы получателем

MUST-3

X

Выбор ISN

Использование основанного на «часах» генератораISN

MUST-8

X

Защищённый генератор ISN с применением PRF

SHLD-1

X

Расчёт PRF вне хоста

MUST-9

X

Создание соединений

SYN-RECEIVED запоминает последнее состояние

MUST-11

X


Пассивные вызовы OPEN могут влиять на другие записи (TCB)

MUST-41

X

Одновременно несколько LISTEN на одном порту

MUST-42

X

Спрашивать при необходимости адрес отправителя у уровня IP

MUST-44

X

  • иначе использовать локальный адрес соединения

MUST-45

X

Вызов OPEN с групповым или широковещательным адресом IP

MUST-46

X

Отбрасывание сегментов, переданных по групповому или широковещательному адресу

MUST-57

X

Закрытие соединений

RST может включать данные

SHLD-2

X

Информирование приложения о прерванном (abort) соединении

MUST-12

X

Полудуплексное закрытие соединений

MAY-1

X

передача RST для индикации потери данных

SHLD-3

X

Состояние TIME-WAIT в течение 2MSL

MUST-13

X

  • восприятие SYN в состоянии

MAY-2

X

  • применение Timestamp для сокращения состояния TIME-WAIT

SHLD-4

X

Повторная передача

Реализация экспоненциальной отсрочки, замедленного старта и предотвращения перегрузки

MUST-19

X

Повтор передачи с тем же полем IP Identification

MAY-4

X

Алгоритм Karn

MUST-18

X

Генерация ACK

Агрегирование при наличии возможности

MUST-58

X

Очередь сегментов с нарушением порядка

SHLD-31

X

Обработка всей очереди перед отправкой ACK

MUST-59

X

Передача ACK для сегментов с нарушением порядка

MAY-13

X

Отложенные ACK

SHLD-18

X

  • задержка меньше 0,5 сек

MUST-40

X

  • подтверждать каждый второй полноразмерный сегмент или 2*RMSS принятых данных

SHLD-19

X

Алгоритм предотвращения SWS у получателя

MUST-39

X

Передача данных

Настраиваемое значение TTL

MUST-49

X

Алгоритм предотвращения SWS у отправителя

MUST-38

X

Алгоритм Nagle

SHLD-7

X

  • приложение может отключать алгоритм Nagle

MUST-17

X

Отказы соединений

Рекомендация уровню IP при достижении порога R1

MUST-20

X

Закрывать соединение при достижении порога R2

MUST-20

X

ALP может устанавливать порог R2

MUST-21

X

Информировать ALP об условии R1 <= retxs < R2

SHLD-9

X

Рекомендовать значение для R1

SHLD-10

X

Рекомендовать значение для R2

SHLD-11

X

Тот же механизм для SYN

MUST-22

X

  • R2 для SYN не менее 3 минут

MUST-23

X

Передача пакетов Keep-alive

Передача пакетов Keep-alive:

MAY-5

X

  • приложение может включить и отключить передачу

MUST-24

X

  • по умолчанию передача отключена

MUST-25

X

  • передача только в интервале бездействия

MUST-26

X

  • настраиваемый интервал передачи

MUST-27

X

  • интервал по умолчанию не менее 2 часов

MUST-28

X

  • устойчивость к потере ACK

MUST-29

X

  • передача без данных

SHLD-12

X

  • настраиваемая передача «сорного» октета данных

MAY-6

X

Опции IP

Игнорировать опции, не понятные TCP

MUST-50

X

Поддержка временных меток

MAY-10

X

Поддержка записи маршрута

MAY-11

X

Source Route

  • ALP может задавать маршрут

MUST-51

X

  • переписывать Source Route в дейтаграмме

MUST-52

X

  • построение обратного пути из Source Route

MUST-53

X

  • переписывание маршрута по более новым данным

SHLD-24

X

Приём сообщений ICMP от IP

Приём сообщений ICMP от IP

MUST-54

X

  • Destination Unreachable (0,1,5) передаётся ALP

SHLD-25

X

  • прерывание соединения по Destination Unreachable (0,1,5)

MUST-56

  • Destination Unreachable (2 – 4) ведёт к разрыву соединения

SHLD-26

X

  • отбрасывание сообщений Source Quench

MUST-55

X

  • прерывание соединения по сообщению Time Exceeded

MUST-56

X

X

  • прерывание соединения по сообщению Parameter Problem

MUST-56

X

Проверка пригодности адресов

Отклонять вызовов OPEN для недействительного адреса IP

MUST-46

X

Отклонять SYN с недействительного адреса IP

MUST-63

X

Отбрасывать SYN с групповым или широковещательным адресом IP

MUST-57

X

Службы интерфейса TCP – ALP

Механизм отчётов об ошибках

MUST-47

X

ALP может отключать процедуру отчётов об ошибках

SHLD-20

X

ALP способна задавать поле Diffserv для передачи

MUST-48

X

  • передача Diffserv уровню IP без изменений

SHLD-22

X

ALP может менять поле Diffserv в процессе работы соединения

SHLD-21

X

ALP меняет поле Diffserv в процессе работы соединения

SHLD-23

X

Передача ALP полученного поля Diffserv

MAY-9

X

Вызов FLUSH

MAY-14

X

Поддержка локального адреса IP в параметре OPEN

MUST-43

X

Поддержка RFC 5961

Реализация защиты от внедрения данных

MAY-12

X

Явное уведомление о перегрузке

Поддержка ECN

SHLD-8

X

Дополнительный контроль перегрузки

Реализация дополнительных совместимых алгоритмов

MAY-18

X

Благодарности

Этот документ в значительной части является пересмотром RFC 793, редактором которого был Jon Postel. Благодаря его превосходной работе документ просуществовал три десятилетия без пересмотра.

Andre Oppermann участвовал в редактировании первой редакции этого документа.

Авторы признательны руководителям рабочей группы IETF TCPM за помощь в подготовке этого документа: Michael Scharf, Yoshifumi Nishida, Pasi Sarolahti, Michael Tüxen.

При обсуждении этой работы в почтовой конференции TCPM, на встречах рабочей группы и обзорах в рамках направления полезные комментарии, критику и рецензии предоставили (в алфавитном порядке фамилий) Praveen Balasubramanian, David Borman, Mohamed Boucadair, Bob Briscoe, Neal Cardwell, Yuchung Cheng, Martin Duke, Francis Dupont, Ted Faber, Gorry Fairhurst, Fernando Gont, Rodney Grimes, Yi Huang, Rahul Jadhav, Markku Kojo, Mike Kosek, Juhamatti Kuusisaari, Kevin Lahey, Kevin Mason, Matt Mathis, Stephen McQuistin, Jonathan Morton, Matt Olson, Tommy Pauly, Tom Petch, Hagen Paul Pfeifer, Kyle Rose, Anthony Sabatini, Michael Scharf, Greg Skinner, Joe Touch, Michael Tüxen, Reji Varghese, Bernie Volz, Tim Wicinski, Lloyd Wood, Alex Zimmermann.

Joe Touch предоставил дополнительную помощь в прояснении описания параметров размера сегмента и рекомендации для PMTUD/PLPMTUD. Markku Kojo помог собрать воедино текст раздела по контролю перегрузок TCP.

Этот документ включает содержимое присланных замечаний об ошибках, присланных (в хронологическом порядке) Yin Shuming, Bob Braden, Morris M. Keesan, Pei-chun Cheng, Constantin Hagemeier, Vishwas Manral, Mykyta Yevstifeyev, EungJun Yi, Botong Huang, Charles Deng, Merlin Buge.

Адрес автора

Wesley M. Eddy (editor)
MTI Systems
United States of America
Email: wes@mti-systems.com

Перевод на русский язык

Николай Малых

nmalykh@protokols.ru

1Internet Engineering Task Force – комиссия по решению инженерных задач Internet.

2Internet Engineering Steering Group – комиссия по инженерным разработкам Internet.

3Application-Layer Program – программа прикладного уровня.

Рубрика: RFC | Оставить комментарий

RFC 9273 Network Coding for Content-Centric Networking / Named Data Networking: Considerations and Challenges

image_print
Internet Research Task Force (IRTF)                         K. Matsuzono
Request for Comments: 9273                                     H. Asaeda
Category: Informational                                             NICT
ISSN: 2070-1721                                              C. Westphal
                                                                  Huawei
                                                             August 2022

Network Coding for Content-Centric Networking / Named Data Networking: Considerations and Challenges

Сетевое кодирование для CCNx и NDN – соображения и проблемы

PDF

Аннотация

Этот документ описывает текущие результаты исследований сетевого кодирования (Network Coding или NC) для ориентированных на содержимое сетей (Content-Centric Networking или CCNx) и сетей именованных данных (Named Data Networking или NDN) и разъясняет технические вопросы и возможные проблемы при использовании NC в CCNx/NDN. Документ является результатом работы исследовательских грапп Coding for Efficient Network Communications (NWCRG) и Information-Centric Networking (ICNRG).

Статус документа

Документ не относится к категории Internet Standards Track и публикуется лишь для информации.

Документ является результатом работы IRTF1. IRTF публикует результаты относящихся к Internet исследований и разработок. Эти результаты могут оказаться не пригодными для реализации. Данный RFC представляет согласованное мнение исследовательской группы Coding for Efficient Network Communications в рамках IRTF. Документы, одобренные для публикации IRSG, не претендуют на статус Internet Standard (см. раздел 2 в RFC 7841).

Информацию о текущем статусе документа, ошибках и способах обратной связи можно найти по ссылке https://www.rfc-editor.org/info/rfc9273.

Авторские права

Авторские права (Copyright (c) 2022) принадлежат IETF Trust и лицам, указанным в качестве авторов документа. Все права защищены.

К документу применимы права и ограничения, указанные в BCP 78 и IETF Trust Legal Provisions и относящиеся к документам IETF (http://trustee.ietf.org/license-info), на момент публикации данного документа. Прочтите упомянутые документы внимательно.

Оглавление

Исключено в версии HTML.

1. Введение

Информационно-ориентированные сети (Information-Centric Networking или ICN), в целом, ориентированные на содержимое сети (Content-Centric Networking или CCNx) [1] или сети именованных данных (Named Data Networking или NDN) [2], в частности, появились как новая парадигма коммуникаций, основанная на извлечении данных по их именам. Эта парадигма продвигает сведения о содержимом на сетевой уровень. Предполагается, что это позволит потребителям получать нужные сведения (содержимое) простым и эффективным способом из разнородных сетей, к которым они могут быть подключены. Архитектура CCNx/NDN представила новые идеи и стимулировала исследования в различных областях, таких как кэширование в сети, маршрутизация по именам, транспортировка по нескольким путям, защита содержимого. Одним из важных преимуществ запроса содержимого по именам устраняет необходимость организации соединения между клиентом и конкретным сервером, а содержимое может быть получено из нескольких источников.

Одновременно с этим в академических и промышленных кругах рос интерес к улучшению понимания фундаментальных аспектов сетевого кодирования (Network Coding или NC) для улучшения показателей пропускной способности, отказоустойчивости и снижения числа передач через соединённые сети и избыточных передач через широковещательные или многоточечные (point-to-multipoint) соединения. NC – это метод, обычно применяемый для кодирования пакетов с тем, чтобы восстановить потерянные исходные пакеты на стороне приёмника для быстрого получения желаемой информации полностью распределенным способом. Кроме того, с точки зрения безопасности, кодированием NC можно управлять с использованием практической схемы защиты, которая справляется с атаками загрязнения (pollution) [3] и может применяться для предотвращения получения злоумышленниками значимой информации [4] или защиты беспроводных видеопотоков при сохранении преимуществ NC [5] [6].

С точки зрения транспортного механизма NC можно разделить на две категории – когерентное NC и некогерентное NC [7] [8]. В когерентном NC исходный и целевой узел знают точную топологию сети и операции кодирования доступны на промежуточных узлах. Когда несколько потребителей пытаются получить одно и то же содержимое, например, видеотрансляцию в реальном времени, когерентное кодирование может обеспечить оптимальную пропускную способность за счёт передачи потока через созданные оптимальные деревья групповой передачи [9]. Однако для этого нужен полностью настраиваемый конкретный механизм маршрутизации и много вычислительных ресурсов для центральной координации. В случае некогерентного NC, где часто применяется случайное линейное кодирование (Random Linear Coding или RLC), не требуется знание топологии сети и операции кодирования на промежуточных узлах [10]. Некогерентное кодирование работает независимо и децентрализовано, поэтому обеспечивает большую гибкость.

NC объединяет пакеты с частями одного содержимого и может делать это в источнике и/или других узлах сети. Закодированные в сети пакеты не связаны с конкретным сервером, поскольку они могут объединяться внутри сети. Поскольку NC фокусируется на том, какую информацию следует кодировать в сетевом пакете, а не на конкретном хосте, где она была создана, это кодирование соответствует архитектуре уровня базовой сети CCNx/NDN. NC позволяет восстановить отсутствующие пакеты за счёт кодирования информации в нескольких пакетах. ICN взаимодействует с NC, поскольку позволяет кэшировать пакеты данных в сети. В типичной сети, использующей NC, отправитель может передать достаточно пакетов для получения исходных данных. ICN предоставляет возможность извлекать кодированные в сети пакеты напрямую из кэшей в сети, делая комбинацию ICN и NC особенно эффективной. Фактически кодирование NC уже реализовано для распространения информации (содержимого) [11] [12] [13]. Montpetit и др. Впервые предложили использовать методы NC для улучшения основных показателей производительности в ICN [14]. Хотя CCNx/NDN превосходно пользуется преимуществами NC (5. Преимущества NC и CCNx/NDN), нужно рассмотреть некоторые технические вопросы объединения NC и CCNx/NDN, связанные с уникальными свойствами CCNx/NDN (6. Технические соображения).

В этом документе рассматривается применение NC к архитектуре CCNx/NDN, приводятся технические соображения и описываются возможные проблемы для случая улучшения взаимодействий на основе CCNx/NDN с применением технологии NC. Следует подчеркнуть, что представление конкретных решений (например, методов оптимизации NC) для улучшения показателей производительности CCNx/NDN за счёт применения NC выходит за рамки документа.

Документ представляет совместные результаты и согласованное мнение исследовательских групп Coding for Efficient Network Communications (NWCRG) и Information-Centric Networking (ICNRG). Документ был прочитан и рецензирован всеми активными участниками этих групп. Он не является результатом IETF или стандартом.

2. Терминология

2.1. Определения, связанные с NC

В этом параграфе приведены связанные с NC термины, определённые в RFC 8406 [15] и предложенные NWCRG.

Source Packet – исходный пакет

Исходящий от источника пакет, содержащий один или несколько исходных символов (source symbol). Исходным символом считается единица данных, происходящих от источника, которая служит входными сведениями для операций кодирования. Например, пакет протокола RTP (Real-time Transport Protocol – транспортировка в реальном масштабе времени) в целом может представлять собой исходный символ. В иных ситуациях (например, для адресации пакетов переменного размера) один пакет RTP может вносить вклад в разные исходные символы.

Repair Packet – ремонтный пакет

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

Encoding versus Recoding versus Decoding – кодирование, запись, декодирование

Кодированием называется операция, принимающая исходные символы и дающая на выходе символы кодирования (encoding symbol) (исходные или кодированные). Запись – это операция, принимающая символы кодирования и дающая на выходе символы кодирования. Декодированием называется операция, принимающая символы кодирования и дающая на выходе исходные символы.

Далее определены термины, связанные с типами кодирования.

Random Linear Coding (RLC) – случайное линейное кодирование

Конкретная форма линейного кодирования с применением набора случайных коэффициентов кодирования. Линейное кодирование выполняет линейную комбинацию набора входных (т. е. исходных и кодированных) символов с использованием данного набора коэффициентов и создаёт ремонтный символ.

Block Coding – блочное кодирование

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

Sliding Window Coding (Convolutional Coding) – кодирование со скользящим окном (свёрточное кодирование)

базовый класс методов кодирования, основанных на скользящем окне кодирования, которое представляет собой набор исходных (кодированных в случае перекодирования) символов, служащих входными данными. Этот метод является альтернативой блочному кодированию.

Fixed or Elastic Sliding Window Coding – кодирование с фиксированным или эластичным скользящим окном

Метод кодирования, создающий кодированные символы «на лету» (обычно с помощью линейного кодирования) из набора исходных символов представленные в скользящем окне кодирования в данный момент. Скользящее окно может иметь фиксированный или переменный во времени размер (эластичное окно). Например, размер окна может зависеть от подтверждений получателей для конкретного исходного символа или исходного пакета (получен, декодирован, пригоден для декодирования).

Ниже приведены термины, относящиеся к низкоуровневым аспектам кодирования.

Rank of the Linear System (Degrees of Freedom) – ранг линейной системы (число степеней свободы)

На приёмной стороне это – число линейно независимых уравнений в линейной системе. Его называют также числом степеней свободы (Degrees of Freedom). Система может быть полноранговой (full rank), когда возможно декодирование, или «частичного ранга» (partial rank), когда возможно лишь частичное декодирование.

Generation (Block) – генерация (блок)

Для блочных кодов это – набор исходных символов входных потоков, которые логически группируются в блок перед выполнением кодирования.

Generation Size (Block Size) – размер генерации (блока)

Для блочных кодов это – число исходных символов, входящих в блок. Оно эквивалентно числу исходных пакетов, если в них содержится по одному исходному символу.

Coding Coefficient – коэффициент кодирования

Для линейного кодирования это – коэффициент в неком конечном поле. Коэффициенты могут выбираться разными способами – например, случайно, из предопределённой таблицы или с использованием предопределённого алгоритма и затравки (seed).

Coding Vector – вектор кодирования

Набор коэффициентов кодирования, служащих для генерации кодированного символа путём линейного кодирования.

Finite Field – конечное поле

Для конечных полей, применяемых в линейных кодах, желательно свойство, состоящее в том, что все элементы (кроме 0) обратимы для сложения и умножения (+ и *) и ни одна операция над элементом не может приводить к переполнению или опустошению (underflow). Примерами конечных полей служат первичные (prime) поля {0..p(m-1)}, где p – простое число. Наиболее часто используются поля с p=2, называемые двоичными полями расширения (binary extension field) {0..2(m-1)}, где m может принимать значение 1, 4, или 8 из практических соображений.

2.2. Определения, связанные с CCNx/NDN

Использованная в документе терминология, связанная с CCNx/NDN, определена в RFC 8793 [16], созданном ICNRG. Она согласуется с документами [17] [18].

3. Основы CCNx/NDN

Здесь кратко описаны основные концепции CCNx/NDN. В сети CCNx/NDN имеется два типа пакетов сетевого уровня – запросы (interest) и пакеты данных (определены в параграфе 3.4 [16]). Термин «объект содержимого» (content object), обозначающий блок данных содержимого, является синонимом пакета данных [16]. Потребитель ICN (определён в параграфе 3.2 [16]) запрашивает объект содержимого путём передачи запроса (interest) и именем данных.

После получения пересылающим элементом ICN (forwarder в соответствии с определением параграфа 3.2 в [16]) запроса interest, он выполняет ряд операций поиска. Сначала проверяется наличие искомого содержимого в кэш-хранилище, называемом хранилищем содержимого (Content Store или CS, как определено в параграфе 3.3 [16]). Если данные найдены, они отправляются запросившему и транзакция считается завершенной.

Если копии не найдено в кэше CS, выполняется поиск в таблице ожидающих запросов (Pending Interest Table или PIT, как определено в параграфе 3.3 [16]) для проверки наличия ожидающих запросов того же объекта содержимого. Если запроса не найдено, создаётся запись в таблице PIT с именем и интерфейсом, откуда получен запрос. Позднее это используется для отправки объекта содержимого, поскольку пакеты interest не включают поля источника, указывающего потребителя. Если запись для этого имени имеется в PIT, она обновляется включением входного интерфейса для этого запроса, а сам запрос отбрасывается.

После поиска в PIT выполняется поиск в таблице пересылки (Forwarding Information Base или FIB, как определено в параграфе 3.3 [16]) для выбора выходного интерфейса. FIB содержит список префиксов имён и соответствующих интерфейсов пересылки для отправки запроса в направлении узла пересылки (forwarder), владеющего копией запрошенных данных.

После извлечения копии данных она передаётся потребителям с использованием следов в записях PIT. Пересылающие узлы удаляют запись о состоянии из PIT при каждом выполнении запроса и могут сохранять данные в своих CS.

Пакеты данных содержат некие сведения для проверки целостности данных и подлинности источника, в частности, сведения о соответствии данных имени [19]. Это нужно потому, что аутентификация объекта очень важна для CCNx/NDN. Однако пересылающие узлы могут пропускать этот этак для повышения скорости обработки.

Важным аспектом CCNx/NDN является отсутствие сессии между потребителем и конкретным сервером. Фактически пересылающий узел или издатель (producer, как определено в параграфе 3.2 [16]), возвращающий объект содержимого, не знает о местоположении потребителя в сети, а тот не знает о местоположении узла, предоставившего содержимое. Теоретически это позволяет запросам interest следовать в сети по разным путям и даже по разным сетям.

4. Основы NC

Тогда как в традиционной сети IP пересылающий узел просто ретранслирует полученные пакеты, NC позволяет такому узлу комбинировать некоторые полученные пакеты данных в один или несколько пакетов для отправки. В этом разделе просто описываются базовые операции NC с упором на RLC в блочном режиме, который хорошо известен как основной метод кодирования.

Для простоты рассмотрим пример сквозного кодирования, где издатель и потребитель выполняют, соответственно, кодирование и декодирование элемента содержимого. Это сквозное кодирование в NC рассматривается как частный случай. Производитель делит содержимое на несколько блоков, называемых генерациями (generation). Кодирование и декодирование выполняется независимо для каждого блока (генерации). Предположим, что каждый блок содержит K исходных пакетов источника с одинаковым размером. Если размеры пакетов различаются, они дополняются нулями до большего. Для создания одного ремонтного пакета в неком блоке издатель линейно комбинирует K исходных пакетов источника, выполняя сложение и умножение с использованием вектора кодирования, содержащего K коэффициентов, которые случайно выбираются из некого конечного поля. Издатель может отвечать на запросы interest, отправляя исходные и ремонтные пакеты в поток содержимого (это называется систематическим кодированием), где ремонтные пакеты обычно применяются для восстановления потерянных исходных пакетов.

Ремонтные пакеты также можно применять для кодирования. Если пересылающие узлы знают каждый вектор кодирования и идентификатор генерации (далее generation ID) принятых ремонтных пакетов, они могут выполнить операцию кодирования (перекодирование), которая является наиболее отличительной чертой NC по сравнению с другими методами кодирования.

На стороне потребителя выполняется декодирование путём решения системы линейных уравнений, представленной векторами кодирования полученных исходных и ремонтных (возможно, лишь ремонтных) пакетов в рамках некой генерации (блока). Для получения всех исходных пакетов потребителю нужно не меньше K линейно независимых пакетов. Иными словами, потребитель должен получить хотя бы K линейно независимых пакетов данных (их называют инновационными). Поскольку приём линейно зависимого пакета данных бесполезен для декодирования, перекодированию следует создавать и представлять инновационные пакеты. Одно из основных преимуществ RLC состоит в том, что даже при конечном поле малого размера (например, q=28), вероятность создания линейно зависимых пакетов пренебрежимо мала [9].

5. Преимущества NC и CCNx/NDN

Сочетание NC и CCNx/NDN может способствовать эффективному крупномасштабному распространению содержимого. По отдельности эти подходы обеспечивают похожие преимущества, такие как повышение производительности и отказоустойчивости. Различие состоит в том, что на транспортном уровне рассматривает поток содержимого как алгебраические данные, которые нужно комбинировать [7], а CCNx/NDN фокусируется на самом содержимом. Поскольку эти подходы дополняют друг друга, их сочетание было бы выгодно и естественно.

Коммуникации на основе имён в CCNx/NDN позволяют потребителям получать искомое содержимое без необходимости создавать и поддерживать сквозные каналы взаимодействия между узлами. Это облегчает использование сетевого кэширования, поиска и извлечения по нескольким путям, а также поддержку мобильности потребителей без необходимости обновлять сведения о местоположении и идентификаторе информации при переходах [1]. Кроме того, коммуникации на основе имён по своей сути поддерживают групповое взаимодействие, поскольку идентичные запросы interest объединяются пересылающими узлами.

NC может позволять транспортной системе CCNx/NDN эффективно распространять и кэшировать данные, связанные с извлечением по нескольким путям [14]. Использование извлечения по нескольким путям и кэширования в сети с помощью NC способствует не только более частому попаданию в кэш, но и повышению уровня анонимности каждого потребителя (данного потребителя может обслуживать набор возможных маршрутизаторов) [20]. Расширение осложняет злоумышленникам получение сведений о потребляемом другими содержимом, способствуя конфиденциальности кэшей. Были представлены другие варианты использования NC в CCNx/NDN, такие как распространение содержимого с кэшированием в сети [21] [22] [23], бесшовная мобильность потребителей [24] [25], малые задержки и потери при доставке видео-потоков [26]. С учётом этого следует рассмотреть интеграцию NC в CCNx/NDN.

6. Технические соображения

В этом разделе приведены соображения по использованию CCNx/NDN с NC с точки зрения сетевой архитектуры и протоколов. Документ фокусируется на NC с блочным кодированием.

6.1. Именование содержимого

Именованные объекты содержимого столь же важны в CCNx/NDN, как именованные хосты в современной сети Internet [19]. В этом параграфе представлены две возможные схемы именования.

6.1.1. Уникальные имена для пакетов NC

Каждый исходный и ремонтный пакет (далее, пакет NC) может иметь уникальное имя, как и каждый исходный объект содержимого в CCNx/NDN, а для работы PIT и CS обычно нужны уникальные имена, идентифицирующие пакеты NC. В качестве метода именования пакетов NC с учётом особенностей блочного кодирования можно использовать вектор кодирования и идентификатор генерации как часть имени объекта содержимого. Как и в [21], для идентификатора генерации g-id, размера генерации (блока) 4 и вектора кодирования (1,0,0,0) имя может иметь вид /CCNx.com/video-A/g-id/1000. Можно также применять некоторые другие идентификаторы, связанные со схемой кодирования. Например, может применяться идентификатор кодирования enc-id, задающий схему, как в /CCNx.com/video-A/enc-id/g-id/1000, определённом в FEC Framework (FECFRAME) [27]. Эта схема именования проста и может поддерживать доставку пакетов NC с такими же операциями в PIT/CS как для объектов содержимого.

При использовании схемы именования содержимого, подобной описанной здесь, запрос interest для пакета NC может иметь полное имя, включающее идентификатор генерации и вектор кодирования (/CCNx.com/video-A/g-id/1000) или только префикс имени, включающий лишь generation ID (/CCNx.com/video-A/g-id). В первом случае пересылающими просто выполняется точное сопоставление с PIT (как в CCNx/NDN). Потребитель способен указать и получить инновационный пакет, требуемый для успешного декодирования. Это может перенести генерацию вектора кодирования от пересылающего узла к потребителю.

Во втором случае требуется частичное сопоставление имени у пересылающего. Поскольку interest лишь с префиксом имени соответствует любому пакету NC с таким же префиксом, потребитель может сразу же получить пакет NC от соседнего CS (из сетевого кэша), не зная заранее векторов кодирования в кэшированных пакетах NC. Когда пакеты NC при передаче изменяются путём перекодирования в сети, выполняемого пересылающими, потребитель также может получить изменённые пакеты NC. Однако в отличие от первого случая у него может не быть достаточной свободы (см. параграф 6.2.3. Работа пересылающего). Для решения этой проблемы может потребоваться новый тип TLV в сообщениях interest для указания дополнительных сведений о кодировании, чтобы ограничить число получаемых пакетов NC. Например, это можно сделать путём задания векторов кодирования инновационных пакетов для потребителя (их называют матрицами декодирования) как в [14]. Это расширение может повлечь существенный рост размера пакетов interest, поэтому может оказаться полезным использование для векторов кодирования механизмов сжатия [28] [29]. Без таких сведений о кодировании, представляемых в interest, пересылающему придётся поддерживать записи о запросах interest, которые были выполнены ранее (см. 6.2.3. Работа пересылающего).

6.1.2. Неуникальные имена для пакетов NC

Пакет NC может иметь имя, указывающее, что это пакет NC, и переносить сведения о кодировании в поле метаданных внутри содержимого (т. е. имя включает тип данных, исходный или ремонтный пакет). Это было бы невыгодно для приложений, которым не нужно понимать содержимое пакета (payload). Из-за того, что несколько пакетов NC могут иметь одно имя, для потребителя требуется механизм получения инновационных пакетов. Как указано в параграфе 6.3. Кэширование в сети, требуется также механизм для поддержки множества инновационных пакетов в CS. Кроме того, при шифровании содержимого возникают дополнительные расчётные издержки.

6.2. Транспорт

Основанная на вытягивании (pull) функция запросов-откликов CCNx/NDN является там фундаментальным транспортным подходом – для одного запроса interest извлекается не более одного пакета данных. Это значит, что пересылающий или издатель не могут внедрить незапрошенные пакеты данных по своей инициативе. Считается важным соблюдение этого правила, поскольку нарушение 1) приведёт к атакам с отказом в обслуживании (DoS), 2) сделает непригодными имеющиеся подходы к управлению перегрузкой на основе этого правила и 3) снизит эффективность имеющихся подходов к мобильности потребителей. Таким образом, для применения NC в CCNx/NDN. Следует рассмотреть описанную ниже базовую операцию. Тем не менее, при нарушении правила указанные проблемы безопасности должны быть решены.

6.2.1. Область действия NC

Не решён вопрос относительно возможности пересылающего выполнить перекодирование в сети для полученных транзитных пакетов данных или операции NC можно выполнять только для данных, которые соответствуют interest. В последнем случае кодирование или перекодирование выполняется для генерации пакета на лубом пересылающем узле, способном ответить на interest. Это возможно, когда каждый пакет NC имеет уникальное имя, а interest имеет полное имя. С другой стороны, если interest имеет частичное имя без сведений о векторе кодирования или несколько пакетов NC имеют одно имя, может возникнуть первый случай и перекодирование может происходить в любом месте сети, где возможно изменить полученный пакет NC и переслать его. Поскольку CCNx/NDN включает механизмы обеспечения целостности данных в процессе передачи, кодирование в сети будет вызывать сложности, связанные с обеспечением работы механизмов защиты целостности. Точно так же может быть полезно сетевое кэширование пакетов NC на пересылающих узлах, однако им потребуется тот или иной механизм для проверки пригодности пакетов NC (см. 9. Вопросы безопасности).

6.2.2. Работа потребителя

Чтобы воспользоваться преимуществами NC (возможно, связанными с кэшированием в сети), потребитель должен отправлять запросы interest, которые направляют пересылающего (или издателя) отвечать инновационными пакетами, когда они доступны. В случае, когда каждый пакет NC может иметь уникальное имя (как описано в параграфе 6.1. Именование содержимого), отправка interest с указанием уникального имени в g-id и вектора кодирования для пакета NC даёт потребителю возможность получить инновационный пакет, если такой доступен у некоторых пересылающих.

Чтобы задать точное имя пакета NC для извлечения, потребитель должен знать действительную схему именования. С практической точки зрения желательно, чтобы приложение потребителя автоматически создавало верные компоненты имени независимо от каких-либо спецификаций приложения. С этой целью приложение-потребитель может получить и указать (сослаться) манифест [17], указывающий объекты содержимого, включая пакеты NC, или использовать какой-либо спецификатор схемы кодирования как часть имени при создании компонентов имени в interest для запроса инновационных пакетов.

И наоборот, потребитель без возможности декодирования (например, конкретный датчик) может пожелать получать лишь исходные пакеты. Как указано в параграфе 6.1. Именование содержимого, поскольку пакет NC может иметь имя, явно отличающееся от исходных пакетов, возможна передача interest для извлечения лишь исходных пакетов.

6.2.3. Работа пересылающего

Если пересылающий постоянно отвечает на входящие interest неинновационными пакетами, потребители не могут декодировать и получить исходные пакеты. Эта проблема возникает, когда 1) входящие interest для пакетов NC не задают некоторые параметры кодирования, такие как векторы кодирования для применения, и 2) у пересылающего нет достаточного числа линейно независимых пакетов NC (возможно в CS) для использования при перекодировании. В этом случае пересылающий должен определить, может ли он генерировать инновационные пакеты для пересылки на интерфейсы, с которых поступил запрос interest. Подход к решению этой задачи состоит в том, что пересылающий узел ведёт учёт interest для конкретных имён, generation ID и входных интерфейсов, чтобы записать число уже предоставленных степеней свободы [21]. Поскольку такая схема требует поддержки состояний (возможно, и таймеров) на узлах пересылки, должны учитываться вопросы расширяемости и практичности. Кроме того, потребоваться некоторые транспортные механизмы для обнаружения и восстановления потерь в сети [25][26] на узлах пересылки, а также управляемые потребителем механизмы для быстрого восстановления потерь и достижения преимуществ NC. Если пересылающий не может вернуть соответствующий инновационный пакет из локального хранилища содержимого или создать «на лету» перекодированный пакет, являющийся инновационным, важно, чтобы пересылающий не просто возвращал неинновационный пакет, а выполнял поиск пересылки в своей базе FIB и пересылал запрос interest в направлении издателя или восходящего пересылающего узла, способного обеспечить инновационный пакет. В этом контексте для эффективного и быстрого поиска инновационного пакета следует рассматривать подобающую настройку FIB и эффективную стратегию пересылки interest.

В другом возможном случае, когда запросы interest принимаются лишь для исходных пакетов, пересылающий узел может попытаться декодировать и получить все исходные пакеты и сохранить их (при доступности полной ёмкости кэша), позволяя тем самым ускоренные отклики на последующие interest. Поскольку кодирование или перекодирование связано с вычислительными издержками, пересылающий узел должен определить, как отвечать на полученные запросы interest в соответствии с вариантом применения (например, в чувствительном или устойчивом к задержкам приложении) и своими условиями, такими как доступность пространства в кэше и вычислительные возможности.

6.2.4. Работа издателя

Перед выполнением NC для конкретного содержимого в CCNx/NDN издатель должен обеспечить (отвечает за) разделение всего содержимого на более мелкие объекты для предотвращения фрагментации пакетов, которая может вызывать избыточную обработку и снижать пропускную способность. Размер содержимого должен соответствовать допустимому размеру пакетов, чтобы избежать фрагментирования в сети CCNx/NDN. Издатель выполняет операции кодирования для набора небольших объектов содержимого и именования для пакетов NC.

Если производитель берет на себя роль ведущего при определении применяемых векторов кодирования при генерации пакетов NC, имеется 3 общих стратегии именования и создания пакетов NC, указанные ниже.

  1. Потребители сами понимают детали соглашений об именовании для пакетов NC и, таким образом, могут передавать соответствующие запросы interest в направлении издателя для получения пакетов NC, для которых параметры кодирования уже заданы издателем.

  2. Издатель определяет векторы кодирования и генерирует пакеты NC после получения запросов interest, задающих пакеты, которые потребитель хочет получить.

  3. Схема именования для задания векторов кодирования и соответствующих пакетов NC явно представлена через манифест (например, FLIC [30]), который может быть получен потребителем и использован для выбора среди доступных векторов кодирования и соответствующих пакетов, чтобы передать соответствующие interest.

В первом случае, хотя потребители не могут гибко задавать вектор кодирования для генерации пакетов NC, которые хочется получить, задержка получения пакета NC будет меньше, чем в двух других случаях. Во втором случае возникает расплата в виде задержки на дополнительные операции NC, выполняемые после получения interest. В третьем случае пакеты NC для включения в манифест, должны заранее рассчитываться издателем (поскольку манифест указывает пакеты NC хэш-значениями, а не именами), но издатель может выбрать, что включать в манифест, и создать несколько манифестов с разными вариантами кодирования заранее или по запросу, если нужно.

Общим преимуществом двух первых подходов к сквозному кодированию является то, что при добавлении издателем подписей к пакетам NC становится возможной проверка пригодности данных на всем протяжении (как в случае работы CCNx/NDN без NC). Третий подход с использованием манифеста компенсирует дополнительную задержку, вносимую необходимостью извлечения манифеста тем, что подписывается лишь манифест, а не отдельные пакеты NC.

6.2.5. Совместимость с прежними версиями

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

6.3. Кэширование в сети

Кэширование является полезным методом повышения пропускной способности и снижения задержки в разных приложениях. Сетевое кэширование в CCNx/NDN, по сути, обеспечивает поддержку на сетевом уровне и является выгодным за счёт вовлечения NC для обеспечения эффективной групповой передачи [31], извлечения данных по нескольким путям [21] [24] и быстрого восстановления потерь [26]. Однако требуется рассмотреть несколько вопросов.

Как правило ёмкость CS ограничена и политика кэширования влияет на производительность потребителя [32] [33] [34]. Поэтому для пересылающих очень важно определить, какие объекты содержимого следует кэшировать, а какие – отбрасывать. Поскольку чувствительным к задержкам приложениям часто не требуется долговременное кэширование в сети из-за ограничений, связанных с реальным масштабом времени, пересылающие должны знать о необходимости кэширования полученных объектов содержимого для сохранения объёма кэша. В CCNx это можно сделать установкой рекомендуемого времени кэширования (Recommended Cache Time или RCT) в необязательном заголовке пакета данных на стороне издателя. RCT служит рекомендацией для CS-кэша спри определении срока хранения кэшированного объекта. При RCT = 0 пересылающий считает кэширование бесполезным, а при больших значениях RCT кэшировать объекты на длительное время.

Одним из важных аспектов кэширования в сети является возможность пересылающих кэшировать пакеты NC в своих CS. Они могут кэшировать пакеты NC, не имея возможности проверить пригодность объектов содержимого, поэтому для кэширования пакетов NC нужен механизм проверки пакетов NC (см. 9. Вопросы безопасности). Когда пакеты NC имеют одно имя, нужен также какой-либо механизм их идентификации.

6.4. Беспрепятственная мобильность потребителей

Важным свойством CCNx/NDN является отсутствие сессий, позволяющее потребителю и пересылающим передавать множество запросов interest параллельно в направлении разных копий содержимого с одновременным асинхронным использованием нескольких интерфейсов. За счёт извлечения данных по нескольким путям потребитель может получить содержимое из нескольких копий, распространяемое с использованием суммарной производительности нескольких интерфейсов. Для связывания нескольких копий потребитель может воспользоваться тем или иным механизмом адаптации потокового видео [24] или контроль перегрузок для получения содержимого [35].

NC добавляет в CCNx уровень надёжности распределенным и асинхронным способом, поскольку в NC обеспечивается механизм, гарантирующий для нескольких запросов interest, переданных параллельно разным копиям содержимого, получение инновационных пакетов даже в случаях потери пакетов на некоторых путях к этим копиям. Это относится к перемещению (мобильности) потребителя [24], когда тот может получить дополнительные степени свободы с любым инновационным пакетом, если в процессе перемещения имеется хотя бы один доступный интерфейс. Стратегия пересылки interest у потребителя (возможно, и у пересылающего) будет нужна потребителю для получения инновационных пакетов с сохранением беспрепятственной мобильности.

7. Проблемы

В этом разделе представлены некоторые проблемы и направления исследования, связанные с применением NC в CCNx/NDN.

7.1. Адаптация свёрточного кодирования

К настоящему времени предложено несколько подходов к блочному кодированию, тем не менее, в CCNx/NDN до сих пор нет достаточного рассмотрения и применения свёрточного кодирования (например, со скользящим или эластичным окном). Свёрточное кодирование часто подходит для случаев, когда нужна частично или полностью гарантированная доставка непрерывного потока данных, особенно в реальном масштабе времени. Как и в [36], на основе сквозного кодирования для непрерывного потока содержимого было бы выгодно применять кодирование со скользящим окном в CCNx/NDN. В этом случае издатель должен соответствующим образом установить параметры кодирования и сообщить сведения потребителям, а те должны передавать запросы interest, дополненные информацией о состоянии приёма и декодирования данных. Поскольку CCNx/NDN применяет поэтапное (hop-by-hop) состояние пересылки, было бы целесообразно обсудить и исследовать применение свёрточного кодирования в стиле hop-by-hop и возможные преимущества. В частности, для случаев, когда сетевое перекодирование может происходить в узлах пересылки, потребуется управление окном кодирования и CS, для чего следует соответствующие возможности и практичность.

7.2. Контроль скорости и перегрузки

Добавление избыточности за счёт ремонтных пакетов может привести к дополнительному насыщению сети и отрицательно повлиять на общую пропускную способность. В частности, для случаев, когда более желательно беспристрастное распределение общей полосы, каждый поток содержимого должен адаптироваться к условиям в сети для справедливого распределения доступной полосы канала. Таким образом, все потоки содержимого должны совместно реализовать контроль перегрузок для регулирования потребляемой полосы [37]. Это требует эффективного подхода к развёртыванию (например, поддерживаемый пересылающими контроль перегрузки может обеспечить преимущества при частичном развёртывании).

Как описано в параграфе 6.4. Беспрепятственная мобильность потребителей, NC может способствовать беспрепятственной мобильности потребителей за счёт получения инновационных пакетов путём извлечения данных по нескольким путям без дубликатов, а предотвращение дубликатов способствует контролю перегрузок. Разработка эффективного механизма управления скоростью и контроля перегрузок для обеспечения мобильности потребителей при одновременном повышении общей пропускной способности и снижении задержек за счёт полного использования операций NC может оказаться сложной задачей.

7.3. Безопасность

Хотя CCNx/NDN создаёт новые проблемы безопасности на сетевом уровне, отличающемся от традиционных сетей IP, такие как отравление кэша, атаки с загрязнением и DoS-атаки с использованием пакетов interest, некоторые подходы в обеспечению безопасности уже представлены [19] [38]. Применение NC в CCNx/NDN связано с двумя аспектами безопасности, которые требуется учитывать.

Первый вопрос связан с записью на пересылающих узлах. Требуется тот или иной механизм защиты целостности пакетов NC, недавно созданных перекодированием в сети, чтобы потребители и другие пересылающие получали действительные пакеты NC. Для этого имеется несколько подходов, рассмотренных в разделе 9. Вопросы безопасности, но возможны и более эффективные методы с меньшей сложностью и вычислительными затратами.

Другой вопрос связан с вредоносными запросами атакующих и внедрением пакетов NC, которые могут усиливать некоторые атаки. Поскольку пакеты NC мало применяются в общем случае, они могут быть нацелены на загрязнение кэша менее частыми запросами, которое будет препятствовать кэшированию на основе популярности запросов. С такими атаками необходимо бороться для поддержки эффективности кэширования в сети. За счёт внедрения недействительных пакетов NC с целью заполнения CS на узлах пересылки влияние атак с отравлением кэша будет зависеть от степени контроля целостности пакетов NC. В предположении, что каждый пакет NC имеет действительную подпись, прямой подход будет заключаться в проверке подписи пересылающими узлами «на лету» с сохранением и пересылкой только проверенных пакетов NC. Однако проверка подписи пересылающими узлами со скоростью линии может оказаться невозможной, поэтому следует рассмотреть механизмы распределения и снижения такой нагрузки для сохранения преимуществ кэширования в сети, таких как сокращение задержек и нагрузки на сеть.

7.4. Расширяемость маршрутизации

В CCNx/NDN протокол маршрутизации по именам без процесса распознавания (resolution) упрощает процесс маршрутизации и сокращает общую задержку. В маршрутизации IP рост размера таблиц маршрутизации стал проблемой. Таким образом, необходимо применять схему иерархического именования, чтобы улучшить расширяемость маршрутизации за счёт агрегирования маршрутных данных.

Для реализации преимуществ NC потребителям нужно эффективно получать инновационные пакеты с применением механизмов CCNx/NDN для извлечения по нескольким путям. Это требует наличия эффективного механизма маршрутизации для подобающего заполнения таблиц FIB, а также эффективной пересылки запросов interest. Такая координация может препятствовать расширяемости маршрутизации. Будет сложно обеспечить эффективную и расширяемую маршрутизацию запросов interest для пакетов NC с одновременным упрощением процесса маршрутизации.

8. Взаимодействие с IANA

Этот документ не требует действий IANA.

9. Вопросы безопасности

Перекодирование в сети является отличительной чертой NC. Запрашиваться и применяться (возможно, сохраняться) должны лишь действительные пакеты NC, созданные перекодированием в сети. Для решения этой задачи имеется несколько подходов. Во-первых, это проверка подписей с возможностью использования нескольких подписей. Это позволяет иметь свой уникальный ключ подписи не только исходному издателю содержимого, но и некоторым пересылающим, ответственным за перекодирование в сети. Каждый пересылающий узел группы подписывает созданный недавно пакет NC, чтобы другие узлы могли проверить данные по этой подписи. CS может проверять подписи пакетов NC перед их сохранением, чтобы не кэшировать недействительные пакеты. Во-вторых, потребители могут вносить ограничения для правил сопоставления, используя только имя запрошенных данных. Неоднозначность запросов interest можно устранить, задавая имя и идентификатор ключа (дайджест открытого ключа издателя) для сопоставления с запрошенными данными. Такое ограничение KeyId встроено в CCNx [17]. Пересылаются и хранятся в CS лишь пакеты, соответствующие interest и KeyId, что снижает возможности отравления кэша. Кроме того, в CCNx имеется правило, которому подчиняются CS, для предотвращения усиления непригодных данных. Если для interest задано ограничение KeyId, CS недопустимо отвечать на запрос, пока нет уверенности в корректности подписи соответствующего объекта содержимого. Если CS не может проверить подпись, запрос может считаться отсутствующим в кэше с пересылкой его восходящим (вышестоящим) узлам пересылки. Третьим подходом является поддержка цепочек сертификатов (возможно, без удостоверяющего центра) с использованием того или иного механизма (например, [39]) организации доверенного пути доставки. Этот подход использует механизм поэтапной аутентификации, в котором выполняется сбор сертификатов, объединённый с пересылкой, для создания цепочки сертификатов, обеспечивающей доверие к пути доставки.

В зависимости от принятой стратегии кэширования, такой как правила замены кэша, пересылающим следует соблюдать осторожность при записи и сохранении пакетов NC в CS, поскольку они могут быть частью атаки с загрязнением кэша. Для смягчения таких атак пересылающим узлам следует проверять частоту запросов содержимого, чтобы обнаруживать атаки и иметь возможность ограничивать число запросов, игнорируя некоторые повторяющиеся запросы. Затем они могут принять решение о применении или изменении механизма замены кэша.

Издатели и пересылающие должны уделять пристальное внимание DoS-атакам, нацеленным на создание высокой нагрузки операций NC с использованием запросов interest для пакетов NC. Для смягчения таких атак пересылающие узлы могут ограничивать скорость. Например, они могут отслеживать рост PIT для пакетов NC по содержимому с целью обнаружения атак и ограничения при необходимости частоты прибытия запросов interest. Если приложение NC хочет защитить запрос interest, считающийся активатором NC, для предотвращения таких атак, ему следует рассмотреть применение шифрования и явного протокола.

10. Литература

[1] Jacobson, V., Smetters, D., Thornton, J., Plass, M., Briggs, N., and R. Braynard, “Networking Named Content”, Proc. CoNEXT, ACM, DOI 10.1145/1658939.1658941, December 2009, <https://doi.org/10.1145/1658939.1658941>.

[2] Zhang, L., Afanasyev, A., Burke, J., Jacobson, V., Claffy, K., Crowley, P., Papadopoulos, C., Wang, L., and B. Zhang, “Named data networking”, ACM SIGCOMM Computer Communication Review, vol. 44, no. 3, DOI 10.1145/2656877.2656887, July 2014, <https://doi.org/10.1145/2656877.2656887>.

[3] Gkantsidis, C. and P. Rodriguez, “Cooperative Security for Network Coding File Distribution”, Proc. Infocom, IEEE, DOI 10.1109/INFOCOM.2006.233, April 2006, <https://doi.org/10.1109/INFOCOM.2006.233>.

[4] Cai, N. and R. Yeung, “Secure network coding”, Proc. International Symposium on Information Theory (ISIT), IEEE, DOI 10.1109/ISIT.2002.1023595, June 2002, <https://doi.org/10.1109/ISIT.2002.1023595>.

[5] Lima, L., Gheorghiu, S., Barros, J., Medard, M., and A. Toledo, “Secure Network Coding for Multi-Resolution Wireless Video Streaming”, IEEE Journal of Selected Area (JSAC), vol. 28, no. 3, DOI 10.1109/JSAC.2010.100409, April 2010, <https://doi.org/10.1109/JSAC.2010.100409>.

[6] Vilea, J., Lima, L., and J. Barros, “Lightweight security for network coding”, Proc. ICC, IEEE, DOI 10.48550/arXiv.0807.0610, May 2008, <https://doi.org/10.48550/arXiv.0807.0610>.

[7] Koetter, R. and M. Medard, “An Algebraic Approach to Network Coding”, IEEE/ACM Transactions on Networking, vol. 11, no. 5, DOI 10.1109/TNET.2003.818197, October 2003, <https://doi.org/10.1109/TNET.2003.818197>.

[8] Vyetrenko, S., Ho, T., Effros, M., Kliewer, J., and E. Erez, “Rate regions for coherent and noncoherent multisource network error correction”, Proc. International Symposium on Information Theory (ISIT), IEEE, DOI 10.1109/ISIT.2009.5206077, June 2009, <https://doi.org/10.1109/ISIT.2009.5206077>.

[9] Wu, Y., Chou, P., and K. Jain, “A comparison of network coding and tree packing”, Proc. International Symposium on Information Theory (ISIT), IEEE, DOI 10.1109/ISIT.2004.1365182, June 2004, <https://doi.org/10.1109/ISIT.2004.1365182>.

[10] Ho, T., Medard, M., Koetter, R., Karger, D., Effros, M., Shi, J., and B. Leong, “A Random Linear Network Coding Approach to Multicast”, IEEE Trans. on Information Theory, vol. 52, no. 10, DOI 10.1109/TIT.2006.881746, October 2006, <https://doi.org/10.1109/TIT.2006.881746>.

[11] Dimarkis, A., Godfrey, P., Wu, Y., Wainwright, M., and K. Ramchandran, “Network Coding for Distributed Storage Systems”, IEEE Trans. Information Theory, vol. 56, no.9, DOI 10.1109/TIT.2010.2054295, September 2010, <https://doi.org/10.1109/TIT.2010.2054295>.

[12] Gkantsidis, C. and P. Rodriguez, “Network coding for large scale content distribution”, Proc. Infocom, IEEE, DOI 10.1109/INFCOM.2005.1498511, March 2005, <https://doi.org/10.1109/INFCOM.2005.1498511>.

[13] Seferoglu, H. and A. Markopoulou, “Opportunistic Network Coding for Video Streaming over Wireless”, Proc. Packet Video Workshop (PV), IEEE, DOI 10.1109/PACKET.2007.4397041, November 2007, <https://doi.org/10.1109/PACKET.2007.4397041>.

[14] Montpetit, M., Westphal, C., and D. Trossen, “Network Coding Meets Information-Centric Networking: An Architectural Case for Information Dispersion Through Native Network Coding”, Proc. Workshop on Emerging Name-Oriented Mobile Networking Design (NoM), ACM, DOI 10.1145/2248361.2248370, June 2012, <https://doi.org/10.1145/2248361.2248370>.

[15] Adamson, B., Adjih, C., Bilbao, J., Firoiu, V., Fitzek, F., Ghanem, S., Lochin, E., Masucci, A., Montpetit, M-J., Pedersen, M., Peralta, G., Roca, V., Ed., Saxena, P., and S. Sivakumar, “Taxonomy of Coding Techniques for Efficient Network Communications”, RFC 8406, DOI 10.17487/RFC8406, June 2018, <https://www.rfc-editor.org/info/rfc8406>.

[16] Wissingh, B., Wood, C., Afanasyev, A., Zhang, L., Oran, D., and C. Tschudin, “Information-Centric Networking (ICN): Content-Centric Networking (CCNx) and Named Data Networking (NDN) Terminology”, RFC 8793, DOI 10.17487/RFC8793, June 2020, <https://www.rfc-editor.org/info/rfc8793>.

[17] Mosko, M., Solis, I., and C. Wood, “Content-Centric Networking (CCNx) Semantics”, RFC 8569, DOI 10.17487/RFC8569, July 2019, <https://www.rfc-editor.org/info/rfc8569>.

[18] Mosko, M., Solis, I., and C. Wood, “Content-Centric Networking (CCNx) Messages in TLV Format”, RFC 8609, DOI 10.17487/RFC8609, July 2019, <https://www.rfc-editor.org/info/rfc8609>.

[19] Kutscher, D., Ed., Eum, S., Pentikousis, K., Psaras, I., Corujo, D., Saucez, D., Schmidt, T., and M. Waehlisch, “Information-Centric Networking (ICN) Research Challenges”, RFC 7927, DOI 10.17487/RFC7927, July 2016, <https://www.rfc-editor.org/info/rfc7927>.

[20] Wu, Q., Li, Z., Tyson, G., Uhlig, S., Kaafar, M., and G. Xie, “Privacy-Aware Multipath Video Caching for Content-Centric Networks”, IEEE Journal on Selected Areas in Communications (JSAC), vol. 38, no. 8, DOI 10.1109/JSAC.2016.2577321, June 2016, <https://doi.org/10.1109/JSAC.2016.2577321>.

[21] Saltarin, J., Bourtsoulatze, E., Thomos, N., and T. Braun, “NetCodCCN: a network coding approach for content-centric networks”, Proc. Infocom, IEEE, DOI 10.1109/INFOCOM.2016.7524382, April 2016, <https://doi.org/10.1109/INFOCOM.2016.7524382>.

[22] Wang, J., Ren, J., Lu, K., Wang, J., Liu, S., and C. Westphal, “An Optimal Cache Management Framework for Information-Centric Networks with Network Coding”, Proc. Networking Conference, IFIP/IEEE, DOI 10.1109/IFIPNetworking.2014.6857127, June 2014, <https://doi.org/10.1109/IFIPNetworking.2014.6857127>.

[23] Wang, J., Ren, J., Lu, K., Wang, J., Liu, S., and C. Westphal, “A Minimum Cost Cache Management Framework for Information-Centric Networks with Network Coding”, Computer Networks, Elsevier, DOI 10.1016/j.comnet.2016.08.004, August 2016, <https://doi.org/10.1016/j.comnet.2016.08.004>.

[24] Ramakrishnan, A., Westphal, C., and J. Saltarin, “Adaptive Video Streaming over CCN with Network Coding for Seamless Mobility”, Proc. International Symposium on Multimedia (ISM), IEEE, DOI 10.1109/ISM.2016.0054, December 2016, <https://doi.org/10.1109/ISM.2016.0054>.

[25] Carofiglio, G., Muscariello, L., Papalini, M., Rozhnova, N., and X. Zeng, “Leveraging ICN In-network Control for Loss Detection and Recovery in Wireless Mobile networks”, Proc. of the 3rd ACM Conference on Information-Centric Networking, DOI 10.1145/2984356.2984361, September 2016, <https://doi.org/10.1145/2984356.2984361>.

[26] Matsuzono, K., Asaeda, H., and T. Turletti, “Low Latency Low Loss Streaming using In-Network Coding and Caching”, Proc. Infocom, IEEE, DOI 10.1109/INFOCOM.2017.8057026, May 2017, <https://doi.org/10.1109/INFOCOM.2017.8057026>.

[27] Watson, M., Begen, A., and V. Roca, “Forward Error Correction (FEC) Framework”, RFC 6363, DOI 10.17487/RFC6363, October 2011, <https://www.rfc-editor.org/info/rfc6363>.

[28] Thomos, N. and P. Frossard, “Toward One Symbol Network Coding Vectors”, IEEE Communications Letters, vol. 16, no. 11, DOI 10.1109/LCOMM.2012.092812.121661, November 2012, <https://doi.org/10.1109/LCOMM.2012.092812.121661>.

[29] Lucani, D., Pedersen, M., Ruano, D., Sørensen, C., Heide, J., Fitzek, F., and O. Geil, “Fulcrum Network Codes: A Code for Fluid Allocation of Complexity”, DOI 10.48550/arXiv.1404.6620, April 2014, <https://doi.org/10.48550/arXiv.1404.6620>.

[30] Tschudin, C., Wood, C. A., Mosko, M., and D. Oran, “File-Like ICN Collections (FLIC)”, Work in Progress, Internet-Draft, draft-irtf-icnrg-flic-03, 7 November 2021, <https://datatracker.ietf.org/doc/html/draft-irtf-icnrg-flic-03>.

[31] Maddah-Ali, M. and U. Niesen, “Coding for Caching: Fundamental Limits and Practical Challenges”, IEEE Communications Magazine, vol. 54, no. 8, DOI 10.1109/MCOM.2016.7537173, August 2016, <https://doi.org/10.1109/MCOM.2016.7537173>.

[32] Perino, D. and M. Varvello, “A reality check for content centric networking”, Proc. SIGCOMM Workshop on Information-centric networking (ICN ’11), ACM, DOI 10.1145/2018584.2018596, August 2011, <https://doi.org/10.1145/2018584.2018596>.

[33] Podlipnig, S. and L. Böszörmenyi, “A Survey of Web Cache Replacement Strategies”, Proc. ACM Computing Surveys, vol. 35, no. 4, DOI 10.1145/954339.954341, December 2003, <https://doi.org/10.1145/954339.954341>.

[34] Rossini, G. and D. Rossi, “Evaluating CCN multi-path interest forwarding strategies”, Elsevier Computer Communications, vol. 36, no. 7, DOI 10.1016/j.comcom.2013.01.008, April 2013, <https://doi.org/10.1016/j.comcom.2013.01.008>.

[35] Mahdian, M., Arianfar, S., Gibson, J., and D. Oran, “MIRCC: Multipath-aware ICN Rate-based Congestion Control”, Proc. Conference on Information-Centric Networking (ICN), ACM, DOI 10.1145/2984356.2984365, September 2016, <https://doi.org/10.1145/2984356.2984365>.

[36] Tournoux, P., Lochin, E., Lacan, J., Bouabdallah, A., and V. Roca, “On-the-Fly Erasure Coding for Real-Time Video Applications”, IEEE Transactions on Multimedia, vol. 13, no. 4, DOI 10.1109/TMM.2011.2126564, August 2011, <https://doi.org/10.1109/TMM.2011.2126564>.

[37] Kuhn, N., Lochin, E., Michel, F., and M. Welzl, “Forward Erasure Correction (FEC) Coding and Congestion Control in Transport”, RFC 9265, DOI 10.17487/RFC9265, July 2022, <https://www.rfc-editor.org/info/rfc9265>.

[38] Pentikousis, K., Ed., Ohlman, B., Davies, E., Spirou, S., and G. Boggia, “Information-Centric Networking: Evaluation and Security Considerations”, RFC 7945, DOI 10.17487/RFC7945, September 2016, <https://www.rfc-editor.org/info/rfc7945>.

[39] Li, R., Asaeda, H., and J. Wu, “DCAuth: Data-Centric Authentication for Secure In-Network Big-Data Retrieval”, IEEE Trans. on Network Science and Engineering, vol. 7, no. 1, DOI 10.1109/TNSE.2018.2872049, September 2018, <https://doi.org/10.1109/TNSE.2018.2872049>.

Благодарности

Авторы признательны членам ICNRG и NWCRG, особенно Marie-Jose Montpetit, David Oran, Vincent Roca, Thierry Turletti за их значимые комментарии и предложения.

Адреса авторов

Kazuhisa Matsuzono
National Institute of Information and Communications Technology
4-2-1 Nukui-Kitamachi, Tokyo
184-8795
Japan
Email: matsuzono@nict.go.jp
 
Hitoshi Asaeda
National Institute of Information and Communications Technology
4-2-1 Nukui-Kitamachi, Tokyo
184-8795
Japan
Email: asaeda@nict.go.jp
 
Cedric Westphal
Huawei
2330 Central Expressway
Santa Clara, California 95050
United States of America
Email: cedric.westphal@futurewei.com

Перевод на русский язык

Николай Малых

nmalykh@protokols.ru

1Internet Research Task Force – комиссия по исследовательским задачам Internet.

Рубрика: RFC | Оставить комментарий

Сертификат HTTPS

image_print

Уважаемые господа!
К сожалению срок действия сертификата для сайта истек несколько дней назад и его продление в текущей ситуации пока не представляется возможным.

Вариантов остается три:

  1. обращаться к сайту по протоколу HTTP;
  2. игнорировать предупреждение о том, что сайт не безопасен;
  3. не пользоваться сайтом.

Выбор остается за вами.

Рубрика: Разное | Оставить комментарий

RFC 9285 The Base45 Data Encoding

image_print
Internet Engineering Task Force (IETF)                      P. Fältström
Request for Comments: 9285                                        Netnod
Category: Informational                                     F. Ljunggren
ISSN: 2070-1721                                                    Kirei
                                                          D.W. van Gulik
                                                              Webweaving
                                                             August 2022

The Base45 Data Encoding

Кодирование данных Base45

PDF

Аннотация

Этот документ описывает схему кодирования Base45, основанную на схемах Base64, Base32, Base16.

Статус документа

Документ не относится к категории Internet Standards Track и публикуется лишь для информации.

Документ является результатом работы IETF1 и представляет согласованный взгляд сообщества IETF. Документ прошёл открытое обсуждение и был одобрен для публикации IESG2. Не все одобренные IESG документы являются кандидатами в Internet Standard, см раздел 2 RFC 7841.

Информацию о текущем статусе документа, ошибках и способах обратной связи можно найти по ссылке https://www.rfc-editor.org/info/rfc9285.

Авторские права

Авторские права (Copyright (c) 2022) принадлежат IETF Trust и лицам, указанным в качестве авторов документа. Все права защищены.

К документу применимы права и ограничения, указанные в BCP 78 и IETF Trust Legal Provisions и относящиеся к документам IETF (http://trustee.ietf.org/license-info), на момент публикации данного документа. Прочтите упомянутые документы внимательно. Фрагменты программного кода, включённые в этот документ, распространяются в соответствии с упрощённой лицензией BSD, как указано в параграфе 4.e документа IETF Trust Legal Provisions, без каких-либо гарантий (как указано в Simplified BSD License).

Оглавление

Исключено в версии HTML.

1. Введение

QR-код применяется для представления текста в форме графического образа. В зависимости от символов текста существуют разные варианты кодирования QR, например, численный (Numeric), алфавитно-цифровой (Alphanumeric), байтовый (Byte). Даже в байтовом режиме типичный считыватель кода QR пытается интерпретировать последовательность байтов как текст в кодировке UTF-8 или ISO/IEC 8859-1. Таким образом, коды QR нельзя применять для непосредственного кодирования произвольных двоичных данных и сначала такие данные нужно преобразовать в подходящий текст. По сравнению с имеющимися схемами кодирования Base64, Base32 и Base16, описанными в [RFC4648], описанная здесь схема Base45 обеспечивает более компактный код QR.

Важным отличием Base45 от других схем является таблица ключей и отказ от дополнения символами =.

2. Уровни требований

Ключевые слова необходимо (MUST), недопустимо (MUST NOT), требуется (REQUIRED), нужно (SHALL), не нужно (SHALL NOT), следует (SHOULD), не следует (SHOULD NOT), рекомендуется (RECOMMENDED), не рекомендуется (NOT RECOMMENDED), возможно (MAY), необязательно (OPTIONAL) в данном документе должны интерпретироваться в соответствии с BCP 14 [RFC2119] [RFC8174] тогда и только тогда, когда они выделены шрифтом, как показано здесь.

3. Интерпретация кодированных данных

Кодированные данные интерпретируются в соответствии с [RFC4648], но применяется иной алфавит.

4. Кодирование Base45

Возможности сохранения двоичных данных в QR-коде ограничены. На практике двоичные данные представляются символами в соответствии с одним из режимов, определённых в стандартных кодах QR. Постейший режим называется алфавитно-цифровым (см. параграф 7.3.4 и таблицу 2 в [ISO18004]). К сожалению в режиме Alphanumeric используется 45 различных символов, что делает кодировки Base32 и Base64 неэффективными.

Применяется 45-символьное подмножество US-ASCII – 45 символов пригодны для кода QR в режиме Alphanumeric (см. параграф 7.3.4 и таблицу 2 в [ISO18004]). Base45 представляет 2 байта тремя символами, тогда как Base64 представляет 3 байта четырьмя символами.

При кодировании двух байтов [a, b] они должны интерпретироваться как число n с базой 256, т. е. как целое число без знака размером 16 битов – n = (a * 256) + b. Это число n конвертируется ы [c, d, e] с базой 45 так, что n = c + (d * 45) + (e * 45 * 45). Отметим, что порядок c, d и e выбран так, чтобы самый левых элемент [c] был наименее значимым. Для значений c, d, e выполняется поиск по таблице 1, дающий 3 строки символов. При декодировании процесс обращается.

При кодировании одного байта [a] он должен интерпретироваться как число с базой 256, т. е. как 8-битовое целое число без знака. Это число должно преобразовываться в пару чисел с базой 45 [c d] так, что a = c + (45 * d). Для значений c и d выполняется поиск по таблице 1, дающий 2 строки символов.

Строка байтов [a b c d … x y z] с произвольным содержимым и размером должна кодироваться, как описано здесь. Биты слева направо должны кодироваться в соответствии с приведённым выше описанием. При чётном числе кодируемых байтов кодированная форма имеет размер кратный 3. При нечётном числе кодируемых байтов последний (правый) байт должен кодироваться двумя символами, как указано выше.

При декодировании строк Base45 операции выполняются в обратном порядке.

4.1. Когда Base45 подходит и не подходит

Если двоичные данные предназначены для сохранения в коде QR, предлагаемым механизмом является режим Alphanumeric, использующий 11 битов на 2 символа, как указано в параграфе 7.3.4 [ISO18004]. Индикатор режима расширенной интерпретации канала (Extended Channel Interpretation или ECI) для такого кодирования имеет значение 0010.

Если данные предназначены для передачи иным транспортом, вместо Base45 следует применять соответствующее транспортное кодирование. Например, не рекомендуется сначала использовать Base45, затем кодировать результат с помощью Base64, если данные передаются по электронной почте. В таком случае следует исключить кодирование Base45 и сразу кодировать данные с посощью Base64.

4.2. Используемый в Base45 алфавит

Для режима Alphanumeric определено использование 45 символов, образующих алфавит, как показано в таблице 1.

Таблица 1. Алфавит Base45.

Значение

Символ

Значение

Символ

Значение

Символ

Значение

Символ

00

0

12

C

24

O

36

Пробел

01

1

13

D

25

P

37

$

02

2

14

E

26

Q

38

%

03

3

15

F

27

R

39

*

04

4

16

G

28

S

40

+

05

5

17

H

29

T

41

06

6

18

I

30

U

42

.

07

7

19

J

31

V

43

/

08

8

20

K

32

W

44

:

09

9

21

L

33

X

10

A

22

M

34

Y

11

B

23

N

35

Z

 

4.3. Примеры кодирования

Хотя все представленные примеры показывают кодирование текста, следует отметить, что Base45 подходит для двоичных данных, где каждый октет может иметь любое значение от 0 до 255.

Пример кодирования 1

Строка AB является последовательностью байтов [[65 66]]. Рассматривая все 16 битов, получим 65 * 256 + 66 = 16706. Число 16706 представляется как 11 + (11 * 45) + (8 * 45 * 45), что даёт последовательность чисел с базой 45 [11 11 8]. В соответствии с таблицей 1 получаем кодированную строку BB8.

Таблица 2. Детали примера 1.

AB

Исходная строка

[[65 66]]

Десятичное значение

[16706]

Значение с базой 16

[11 11 8]

Значение с базой 45

BB8

Кодированная строка

 

Пример кодирования 2

Строка Hello!! в кодировке ASCII является последовательностью байтов [[72 101] [108 108] [111 33] [33]]. Рассматривая блоки по 16 битов, получаем [18533 27756 28449 33]. Отметим, что 33 – последний байт. Преобразование в числа с базой 45 даёт [[38 6 9] [36 31 13] [9 2 14] [33 0]], где последний байт представлен 2 значениями. Кодированная строка “%69 VD92EX0” создаётся поиском по таблице 1. Следует отметить наличие в ней пробела.

Таблица 3. Детали примера 2.

Hello!!

Исходная строка

[[72 101] [108 108] [111 33] [33]]

Десятичное значение

[18533 27756 28449 33]

Значение с базой 16

[[38 6 9] [36 31 13] [9 2 14] [33 0]]

Значение с базой 45

%69 VD92EX0

Кодированная строка

 

Пример кодирования 3

Строка “base-45” в кодировке ASCII является последовательностью байтов [[98 97] [115 101] [45 52] [53]]. Рассматривая блоки по 16 битов, получаем [25185 29541 11572 53]. Отметим, что 53 – последний байт. Преобразование в числа с базой 45 даёт [[30 19 12] [21 26 14] [7 32 5] [8 1]] , где последний байт представлен 2 значениями. Кодированная строка имеет форму UJCLQE7W581.

Таблица 4. Детали примера 3.

base-45

Исходная строка

[[98 97] [115 101] [45 52] [53]]

Десятичное значение

[25185 29541 11572 53]

Значение с базой 16

[[30 19 12] [21 26 14] [7 32 5] [8 1]]

Значение с базой 45

UJCLQE7W581

Кодированная строка

 

4.4. Пример декодирования

Пример декодирования 1

Строка QED8WEX0 по результатам поиска в таблице 1 даёт значения [26 14 13 8 32 14 33 0]. Эти числа делятся на блоки по 3, а последний блок содержит 2 числа – [[26 14 13] [8 32 14] [33 0]]. Используя базу 45, получаем числа [26981 29798 33], представляемые байтами [[105 101] [116 102] [33]]. Представление в кодировке ASCII даёт строку “ietf!”.

Таблица 5. Детали примера декодирования.

QED8WEX0

Исходная строка

[26 14 13 8 32 14 33 0]

Результаты поиска в таблице

[[26 14 13] [8 32 14] [33 0]]

Группы по 3 значения

[26981 29798 33]

Преобразование с базой 45

[[105 101] [116 102] [33]]

Значения бейтов (база 8)

ietf!

Декодированная строка

5. Взаимодействие с IANA

Этот документ не требует действий IANA.

6. Вопросы безопасности

При реализации кодирования и декодирования важно соблюдать осторожность, чтобы не возникало переполнения буфера и иных проблем. Это включает расчёты с базой 45 и поиск символов в таблице (Таблица 1). Декодер также должен быть устойчив к вводу, включая подобающую обработку любых значений октетов (0-255), в том числе символов NUL (ASCII 0).

Следует отметить, что Base64 и некоторые иные варианты кодирования дополняют стоки и кодирование начинается с одинакового числа символов, тогда как Base45 избегает дополнения. По этой причине следует особенно осторожно кодировать нечётное число октетов, а также нужно соблюдать осторожность придекодировании последовательностей символов, размер которых не кратен 3.

Кодировки Base используют специально сокращённые варианты алфавита для представления двоичных данных. Не включённые в алфавит символы в base-кодированных данных могут возникать в результате повреждения данных или ошибок реализации. Такие символы могут применяться для создания «скрытого канала», по которому не относящиеся к протоколу данные могут передаваться с враждебными целями. Не включённые в алфавит символы могут также передаваться с целью воспользоваться ошибками реализации, ведущими, например, к переполнению буфера.

Реализации должны отвергать ввод с недействительным кодированием. Например, они должны отвергать ввод (кодированные данные), содержащий не включённые в алфавит символы (Таблица 1), при интерпретации base-кодированных данных.

Хотя строки Base45 содержат лишь символы из таблицы 1, необходимо учитывать некоторые особые случаи. Например, строка FGW представляет число 65535 (FFFF в шестнадцатеричной форме), которое имеет действительное кодирование в 16 битов. Незначительно отличающаяся кодированная строка GGW будет представлять число 65536 (10000 в шестнадцатеричной форме), которое представляется большим, чем 16 числом битов. Реализации должны отвергать данные, содержащие триплеты символов, которые при декодировании дают целые числа без знака больше 65535 (FFFF в шестнадцатеричной форме).

Следует отметить, что строка после кодирования Base45 может включать небезопасные для URL символы, поэтому при включении в URL данных Base45 для безопасности URL следует применять %-кодирование.

7. Нормативные документы

[ISO18004] ISO/IEC, “Information technology — Automatic identification and data capture techniques – QR Code bar code symbology specification”, ISO/IEC 18004:2015, February 2015, <https://www.iso.org/standard/62021.html>.

[RFC2119] Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels”, BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, <https://www.rfc-editor.org/info/rfc2119>.

[RFC4648] Josefsson, S., “The Base16, Base32, and Base64 Data Encodings”, RFC 4648, DOI 10.17487/RFC4648, October 2006, <https://www.rfc-editor.org/info/rfc4648>.

[RFC8174] Leiba, B., “Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words”, BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, <https://www.rfc-editor.org/info/rfc8174>.

Благодарности

Авторы благодарны Mark Adler, Anders Ahl, Alan Barrett, Sam Spens Clason, Alfred Fiedler, Tomas Harreveld, Erik Hellman, Joakim Jardenberg, Michael Joost, Erik Kline, Christian Landgren, Anders Lowinger, Mans Nilsson, Jakob Schlyter, Peter Teufl, Gaby Whitehead за их отклики. Спасибо также всем, кто работал долгие годы с Base64 и подтвердил стабильность реализаций.

Адреса авторов

Patrik Fältström
Netnod
Email: paf@netnod.se
 
Fredrik Ljunggren
Kirei
Email: fredrik@kirei.se
 
Dirk-Willem van Gulik
Webweaving
Email: dirkx@webweaving.org

Перевод на русский язык

Николай Малых

nmalykh@protokols.ru

1Internet Engineering Task Force – комиссия по решению инженерных задач Internet.

2Internet Engineering Steering Group – комиссия по инженерным разработкам Internet.

Рубрика: RFC | Оставить комментарий

RFC 9257 Guidance for External Pre-Shared Key (PSK) Usage in TLS

image_print
Internet Engineering Task Force (IETF)                        R. Housley
Request for Comments: 9257                                Vigil Security
Category: Informational                                       J. Hoyland
ISSN: 2070-1721                                          Cloudflare Ltd.
                                                                M. Sethi
                                                        Aalto University
                                                              C. A. Wood
                                                              Cloudflare
                                                               July 2022

Guidance for External Pre-Shared Key (PSK) Usage in TLS

Рекомендации по применению внешних PSK в TLS

PDF

Аннотация

В этом документе приведены рекомендации по использованию внешних, заранее распределенных ключей (Pre-Shared Key или PSK) в защите транспортного уровня (Transport Layer Security или TLS) версии 1.3, определённой в RFC 8446. Указаны свойства защиты TLS, обеспечиваемые PSK с некоторыми допущениями, и показано, как нарушение этих предположений ведёт к атакам. Даны рекомендации для приложений, помогающие соблюсти эти допущенияю В документе также обсуждаются примеры использования PSK и процессы предоставления, а также указаны свойства защиты и приватности, которые не обеспечиваются TLS 1.3 при использовании внешних PSK.

Статус документа

Документ не относится к категории Internet Standards Track и публикуется лишь для информации.

Документ является результатом работы IETF1 и представляет согласованный взгляд сообщества IETF. Документ прошёл открытое обсуждение и был одобрен для публикации IESG2. Не все одобренные IESG документы являются кандидатами в Internet Standard, см раздел 2 RFC 7841.

Информацию о текущем статусе документа, ошибках и способах обратной связи можно найти по ссылке https://www.rfc-editor.org/info/rfc9257.

Авторские права

Авторские права (Copyright (c) 2022) принадлежат IETF Trust и лицам, указанным в качестве авторов документа. Все права защищены.

К документу применимы права и ограничения, указанные в BCP 78 и IETF Trust Legal Provisions и относящиеся к документам IETF (http://trustee.ietf.org/license-info), на момент публикации данного документа. Прочтите упомянутые документы внимательно. Фрагменты программного кода, включённые в этот документ, распространяются в соответствии с упрощённой лицензией BSD, как указано в параграфе 4.e документа IETF Trust Legal Provisions, без каких-либо гарантий (как указано в Simplified BSD License).

Оглавление

Исключено в версии HTML

1. Введение

В этом документе представлены рекомендации по использованию внешних ключей PSK в TLS 1.3 [RFC8446], применимые также к протоколам Datagram TLS (DTLS) 1.3 [RFC9147] и Compact TLS 1.3 [CTLS]. Для удобочитаемости все они обозначаются в документе как TLS.

Внешние PSK являются симметричными секретными ключами, предоставляемыми реализации протокола TLS извне. Внешние PSK обеспечиваются не через сеть (по внешнему каналу – out of band).

Документ перечисляет защитные свойства TLS, обеспечиваемые PSK при некоторых допущениях, и показывает, как нарушение этих предположений ведёт к атакам. В документе рассматриваются примеры использования PSK, процессы представления и поддержка реализации стека TLS в контексте этих допущений. Документ также предлагает варианты применения, способствующие соблюдению этих допущений.

Имеется много ресурсов с рекомендациями по созданию и проверке паролей в целях повышения защищенности. Однако эквивалентных документов для внешних PSK в TLS нет и здесь этот пробел заполняется.

2. Уровни требований

Ключевые слова необходимо (MUST), недопустимо (MUST NOT), требуется (REQUIRED), нужно (SHALL), не нужно (SHALL NOT), следует (SHOULD), не следует (SHOULD NOT), рекомендуется (RECOMMENDED), не рекомендуется (NOT RECOMMENDED), возможно (MAY), необязательно (OPTIONAL) в данном документе должны интерпретироваться в соответствии с BCP 14 [RFC2119] [RFC8174] тогда и только тогда, когда они выделены шрифтом, как показано здесь.

3. Обозначения

В этом документе логическим узлом (logical node) считается вычислительная сущность (computing presence), с которой другие стороны могут взаимодействовать по протоколу TLS. Логический узел может быть реализован в форме нескольких физических экземпляров (объектов) с единым административным управлением, например, серверной фермы. Конечной точкой (endpoint) называется клиент или сервер, участвующий в соединении.

4. Свойства безопасности PSK

Использование заранее созданных PSK позволяет узлам TLS проверить подлинность отождествлений конечных точек, а также обеспечивает другие преимущества, такие как устойчивость к атакам в присутствии квантовых компьютеров (см. параграф 4.2). Однако эти ключи не обеспечивают защиту приватности (конфиденциальности) отождествлений конечных точек и неотказуемость (одна из точек соединения может отвергнуть диалог), как отмечено в разделе 7.

безопасность аутентификации PSK предполагает одно фундаментальное свойство – каждый ключ PSK известен лишь одному клиенту и одному серверу, которые никогда не меняются ролями. Если это нарушается, защитные свойства TLS существенно ухудшаются, как показано ниже.

4.1. Совместное использование PSK

Как обсуждается в параграфе 5.1 для демонстрации атаки, [AASS19] описывает сценарии, где один ключ PSK используется множеством клиентов и множеством серверов. Если по наивности общий ключ предоставлен всем членам группы, TLS проверяет лишь принадлежность к группе и безопасность системы в целом становится достаточно слабой. Здесь имеется ряд указанных ниже недостатков.

  1. Любой член группы может выдать себя за другого члена этой группы.

  2. Если PSK комбинируется с результатом обмена свежими эфемерными ключами, компрометация члена группы, знающего общий секрет, приводит к доступности этого секрета злоумышленнику для пассивного чтения трафика (и активного его изменения).

  3. Если PSK не комбинируется с результатом обмена свежими эфемерными ключами, компрометация члена группы, знающего общий секрет, приводит к доступности этого секрета злоумышленнику для пассивного чтения всего трафика, включая прошлый (и активного его изменения).

Кроме того, не входящий в группу злоумышленник может перенаправить согласование между действительными членами группы для их соединения непредусмотренным способом, как описано ниже. Отметим, что возможно частичное смягчение этого класса атак – каждый член группы включает расширение для индикации имени сервера (Server Name Indication или SNI) [RFC6066] и прерывает соединение при насовпадении представленного SNI с известным идентификатором принимающей стороны. Подробности этого представлены в [Selfie].

Для иллюстрации атак с перенаправлением рассмотрим трёх парнтеров (A, B, C), знающих общий ключ PSK. Атака модет иметь вид, представленный ниже.

  1. A передаёт ClientHello для B.

  2. Атакующий перехватывает сообщение и перенаправляет его C.

  3. C отвечает (ServerHello, …) узлу A.

  4. A передаёт сообщение для B, завершая согласования якабы с B.

  5. Злоумышленник перенаправляет сообщение Finished узлу to C, что завершает его согласование с A.

В этой атаке проверки подлинности партнёра не происходит. Если C поддерживает более слабый набор шифров, чем B, возможны атаки на снижение (ослабление) криптографического алгоритма. Такое перенаправление является атакой с нарушением привязки отождествления [Krawczyk] [Sethi]. Атака Selfie [Selfie] является особым случаем атаки с перенаправлением против члена группы, который может выступать клиентом и сервером TLS. В этой атаке злоумышленник, не входящий в группу, перенаправляет соединение от клиента к серверу на той же конечной точке.

В дополнение к отмеченным недостаткам общий для узлов ключ PSK может негативно влиять на развёртывание. Например, отзыв отдельных элементов группы становится невозможным без создания нового PSK для оставшихся.

4.2. Энтропия PSK

Свойства энтропии внешних PSK также могут влиять на защитные свойства TLS. Например, при использовании PSK с высокой энтропией режимы организации только ключей PSK обеспечивают ожидаемые защитные свойства TLS, включая организацию одного сеансового ключа между партнёрами, секретность сеансовых ключей, проверку подлинности партнёров и защиту от снижения версии. Разъяснение этих свойств дано в приложении E.1 к [RFC8446]. Однако этим режимам не достает полной защиты (forward security), которая может быть достигнута при использовании режима PSK-DH или краткосрочных PSK.

При использовании PSK с малой энтропией режимы организации только ключей PSK подвержены пассивным атакам с исчерпывающим поиском, которые раскрывают ключи трафика. режимы PSK-DH подвержены активным атакам, в которых злоумышленник выдаёт себя за одну сторону. Фаза исчерпывающего поиска в этих атаках может быть организована в автономном режиме (offline) если атакующий перехватывает одно согласование с применением PSK, но такие атаки не ведут к раскрытию ключей трафика для данного соединения, поскольку ключи зависят также от обмена Диффи-Хеллмана (Diffie-Hellman или DH). Ключи с малой энтропией защизены от активных атак, если с TLS применяется обмен ключами с парольной аутентификацией (Password-Authenticated Key Exchange или PAKE). На момент написания этого документа исследовательская группа Crypto Forum (Crypto Forum Research Group илиCFRG) занималась подготовкой спецификации, рекомендуемых PAKE ([CPACE], [OPAQUE]) для симметричных и асимметричных ключей.

5. Внешние PSK на практике

Шифры PSK были впервые заданы для TLS в 2005 г. Сейчас PSK являются частью спецификации TLS 1.3 [RFC8446]. TLS 1.3 также использует PSK для восстановления сессий. Применяемые для восстановления PSK отличаются от внешних PSK, которые представляются по отдельному каналу (out of band0. В этой спецификации описаны известные варианты применения и процессы представляния для внешних PSK в TLS.

5.1. Примеры использования

В этом параграфе даны некоторые варианты применения, где парные внешние ключи PSK (внешние PSK, совместно применяемые одним клиентом и одним сервером) применяются для аутентификации в TLS. Порядок примеров не отражает каких-либо приоритетов.

Взаимодействие между устройствами с синхронизацией ключей по отдельному каналу

PSK предоставляются по отдельному каналу (out of band) для взаимодействия с известными отождествлениями, при этом отождествление раскрывается через другой online-протокол.

Коммуникации внутри ЦОД

Межмашинное взаимодействие в одном центре обработки данных (ЦОД) или точке присутствия (Point of Presence или PoP) может использовать представленные извне PSK. Это применяется в основном для поддержки соединений TLS с упреждающими данными (early data). Соображения об использовании упреждающих данных с внешними PSK представлены в разделе 8.

Межсерверное взаимодействие без сертификатов

При межмашинном взаимодействии могут применяться предоставленные извне PSK. Это служит в основном для организации соединений TLS без издержек на предоставление и поддержку сертификатов PKI.

Интернет вещей (IoT) и устройства с ограниченными вычислительными возможностями

[RFC7925] задаёт профили TLS и DTLS для устройств с ограниченными ресурсами и предлагает применять шифры PSK для совместимых устройств. Спецификация LwM2M (Open Mobile Alliance Lightweight Machine-to-Machine) [LwM2M] указывает, что серверы LwM2M должны поддерживать режим PSK для DTLS.

Защита RADIUS [RFC2865] с помощью TLS

Шифры PSK не обязательны для этого случая, как указано в [RFC6614].

Аутентификация между пользователем и сервером 3GPP

Базовая архитектура аутентификации (Generic Authentication Architecture или GAA), заданная в 3GPP, указывает, что шифры TLS PSK можно применять между сервером и оборудованием пользователя для аутентификации [GAA].

Смарт-карты

Немецкие карты электронной идентификации (German electronic Identity или eID) поддерживают аутентификацию держателя карты в online-службах на основе TLS PSK [SmartCard].

Квантовая устойчивость

В некоторых развёртывания могут применяться PSK (или их комбинация с аутентификацией на основе сертификатов, как описано в [RFC8773]), благодаря предоставляемой защите от квантовых компьютеров.

Имеются также случаи применения PSK, известных более чем двум объектам. Некоторые примеры приведены ниже (отмечены Ахметзяновой и др. В [AASS19]):

Групповые чаты

В этом случае участникам группы могут быть предоставлены внешние PSK по отдельному каналу (out of band) для организации аутентифицированных соединений с другими членами группы.

IoT и устройства с ограниченными вычислительными возможностями

В этом случае возможно много вариантов представления PSK. Например, а данной системе все устройства IoT могут иметь общий ключ PSK и применять его для взаимодействия с центральным сервером (один ключ на n устройств), иметь свои ключи для взаимодействия с центральным сервером (n ключей на n устройств) или иметь парные ключи для вазаимодействия каждого с каждым (n2 ключей на n устройств).

5.2. Примеры представления

Процесс представления зависит от системных требований и модели угроз. По возможности не следует совместно использовать PSK на узлах, однако иногда этого не избежать. В таких случаях следует использовать рекомендации, приведённые в разделе 6. Ниже приведены примеры процессов представления PSK.

  • Многие промышленные протоколы предполагают, что PSK распределяются и назначаются вручную путём (1) прямого ввода PSK в устройство или (2) использования доверенного при первом применении (trust-on-first-use или TOFU) подхода, когда устройство совсем не защищено до первого входа в систему (login). Многие устройства имеют очень ограниченный пользовательский интерфейс (UI). Например, у них может быть лишь цифровая клавиатура или просто несколько кнопок. Когда подход TOFU не подходит, ключ придётся вводить через ограниченный интерфейс UI.

  • Некоторые устройства представляют PSK по особому (out-of-band) протоколу синхронизации на базе облака.

  • Некоторые секреты могут быть встроены в аппаратные или программные компоненты устройства. Если это делается во время производства, секреты могут указываться на этикетке или включаться в спецификацию (Bill of Materials) для упрощения сканирования или импорта.

5.3. Ограничения при представлении

Системы представления PSK часто ограничены в зависимости от применения. Например, хотя одной из целей представления является обеспечение уникальности каждой пары ключей, некоторые системы не хотят распространять парные общие ключи для достижения этого. Другим примером служит требование некоторых систем встраивать в процессе представления зависимую от приложения информацию в PSK или иные отождествления. Для отождествлений иногда может требоваться маршрутизация, что в настоящее время обсуждается [EAP-TLS-PSK].

6. Рекомендации по использованию внешних PSK

  1. При выводе каждого PSK следует обеспечивать хотя бы 128 битов энтропии, ключ должен быть не короче 128 битов и его следует комбинировать с обменом эфемерными ключами, например, с использованием psk_dhe_ke (Pre-Shared Key Exchange Mode) в TLS 1.3 для полной защиты. Как обсуждалось в разделе 4, PSK с низкой энтропией (т. е. выведенные с использованием менее 128 битов энтропии) подвержены атакам и их следует избегать. Если доступны лишь ключи с малой энтропией, следует применять механизмы организации ключей вроде PAKE, которые могут снизить риск offline-атак по словарю. Отметим, что такие механизмы ещё не стандартизованы и не обязательно будут следовать той же архитектуре, что и процесс встраивания внешних ключей PSK, описанный в [RFC9258].

  2. Если не принято иных мер по снижению риска для PSK, известных группе, использование каждого PSK должно ограничиваться не более чем двумя логическими узлами, один из которых играет роль сервера, другой – роль клиента TLS (логические узлы могут совпадать в разных ролях). В [RFC9258] описаны две меры снижения риска: (1) обмен идентификаторами клиента и сервера через соединение TLS после согласования и (2) встраивание идентификаторов клиента и сервера в строку контекста для импортёра внешнего PSK.

  3. Узлам следует импользовать импортёров внешних PSK [RFC9258] при настройке PSK для пары клиент-сервер, когда это возможно. Импортёры упрощают представление внешних PSK и делают их меньше подверженными ошибкам, выводя уникальный импортируемый PSK из внешнего PSK для каждой поддерживаемом узлом функции вывода ключей (см. раздел «Вопросы безопасности» в [RFC9258]).

  4. По возможности основной ключ PSK (передаваемый импортёру) следует удалять после генерации импортируемых ключей. Это не позволит злоумышленнику использовать компрометацию одного узла для атак на соединения между любыми узлами. Иначе атакующий сможет восстановить основной ключ и снова запустить импортёр.

6.1. Интерфейс стека

Большинство основных реализаций TLS поддерживает внешние PSK. Стеки с поддержкой внешних PSK предоставляют интерфейс, который приложения могут использовать при настройке PSK для отдельных соединений. Детали некоторых имеющихся на момент написания документа стеков приведены ниже.

OpenSSL и BoringSSL

Приложения могут указать поддержку внешних PSK через отдельные шифры в TLS 1.2 и ниже. Они также могут настроить обратные вызовы (callback) для выбора PSK при согласовании. Эти вызовы должны обеспечивать ключ и отождествление PSK. Точный формат обратного вызова зависит от согласованной версии протокола TLS, новые функции обратного вызова специально добавлены в OpenSSL для TLS 1.3 [RFC8446] с поддержкой PSK. Размер PSK проверяется на диапазон 1-256 байтов (включительно), отождествление может иметь размер до 128 байтов.

mbedTLS

Клиентские приложения настраивают PSK до создания соединения путём предоставления встроенного отождествления и значения PSK. Серверы должны реализовать обратные вызовы как в OpenSSL. Отождествление и ключ PSK могут иметь размер от 1 до 16 байтов (включительно).

gnuTLS

Приложения настраивают PSK как необработанные (raw) строки байтов или шестнадцатеричные строки. Отождествление и ключ PSK не проверяются.

wolfSSL

Приложения настраивают PSK с обратными вызовами, подобно OpenSSL.

6.1.1. Кодирование и сравнение отождествлений PSK

Параграф 5.1 в [RFC4279] указывает, чтобы отождествление PSK сначала следует преобразовать в строку символов, а затем кодировать в октеты с применением UTF-8. Это делается для предотвращения проблем совместимости (особено при понятных человеку отождествлениях). С другой стороны, [RFC7925] рекомендует реализациям не применять структурированные форматы для отождествлений PSK и выполнять побайтовое сравнение при любых операциях. При ручной настройке отождествлений PSK важно помнить, что визуально идентичные строки могут отличаться кодировкой.

TLS 1.3 [RFC8446] следует той же практике задания отождествлений PSK последовательностью не обрабатываемых байтов (opaque identity<1..216-1> в спецификации), которые сравниваются побайтово. [RFC8446] требует отождествлений PSK не короче 1 1 и не длиннее 65535 байтов. Хотя [RFC8446] не задаёт строгих требований к формату отождествлений, этот формат может быть разным в зависимости от развёртывания, как указано ниже.

  • Отождествление PSK может быть задаваемой пользователем строкой при использовании с такими протоколами как EAP (Extensible Authentication Protocol) [RFC3748]. Например, gnuTLS считает отождествления PSK именами пользователей.

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

  • При развёртывании следует озаботиться, чтобы размер отождествления позволял предотвратить конфликты.

6.1.2. Конфликты отождествлений PSK

Возможны, хоть и маловероятны, конфликты отождествлений внеших PSK с отождествлениями PSK возобновления. Реализация стека TLS и последовательность обратных вызовов влияют на поведение приложений в случае конфликта. При получении сервером отождествления PSK в TLS 1.3 ClientHello, некоторые стеки TLS выполняют зарегистрированный приложением обратный вызов до проверки кэша возобновления сессий в стеке. Это значит, что при конфликте отождествлений использование внешнего PSK обычно становится предпочтительней восстановления. Поскольку отождествления PSK для восстановления задаёт реализация стека TLS, рекомендуется выделять эти значения так, чтобы можно было отличить PSK возобновления от внешних PSK во избежание конфликтов.

7. Вопросы приватности

Свойства конфиденциальности PSK ортогональны свойствам безопасности, описанным в разделе 4. TLS мало заботится о приватности отождествлений PSK. Например, получает сведения о внешнем PSK или его отождествлении за счёт того, что отождествление открыто передаётся в ClientHello. В результате пассивный противник может связать несколько соединений, использующих один внешний PSK в линии. В зависимости от отождествления PSK пассивный атакующий может также идентифицировать устройство, персону или предприятие, использующее клиент или сервер TLS. Активный злоумышленник может также применить отождествление PSK для помех согласованию или данным приложения от конкретного устройства путём блокировки, задержки или ограничения скорости трафика. Методы снижения таких рисков требуют дополнительного анализа и выходят за рамки документа. Кроме сопоставления устройств в сети внешние PSK по своей природе связаны получателями PSK. В частности, сервер может связывать друг с другом последовательные соединения с одним внешним PSK. Предотвращение этого выходит за рамки документа.

8. Вопросы безопасности

Этот документ посвящён вопросам безопасности. Следует повторить, что имеются опасения, связанные с применением внешних PSK в части подобающей идентификации конечных точек TLS 1.3 и дополнительных рисков при известности внешних PSK группе узлов.

Не рекомендуется применять один ключ PSK более чем на одном клиенте и одном сервере. Однако, как отмечено в параграфе 5.1, имеются приложения, опирающиеся на использование одного PSK множеством узлов. [RFC9258] помогает смягчить перенаправление и отражение в стиле Selfie при использовании одного PSK на множестве узлов. Это достигается корректным применением идентификаторов узлов в конструкции ImportedIdentity.context [RFC9258]. Одним из решений служит выбор каждой конечной точкой одного глобально уникального идентификатора для всех согласования PSK. Таким идентификатором может служить, например, один из MAC-адресов (Media Access Control) точки, 32-битовое случайное значение или UUID (Universally Unique IDentifier) [RFC4122]. Отметим, что такие почтоянные идентификаторы влияют на приватность (см. раздел 7). Каждой конечной точке следует знать идентификатор точки, с которой нужно соединиться и следует сравнивать его с идентификатором из ImportedIdentity.context. Важно помнить, что конечные точки с одним групповым PSK могут представляться друг другом.

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

9. Взаимодействие с IANA

Этот документ не требует действий IANA.

10. Литература

10.1. Нормативные документы

[RFC2119] Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels”, BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, <https://www.rfc-editor.org/info/rfc2119>.

[RFC8174] Leiba, B., “Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words”, BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, <https://www.rfc-editor.org/info/rfc8174>.

[RFC8446] Rescorla, E., “The Transport Layer Security (TLS) Protocol Version 1.3”, RFC 8446, DOI 10.17487/RFC8446, August 2018, <https://www.rfc-editor.org/info/rfc8446>.

[RFC9258] Benjamin, D. and C. A. Wood, “Importing External Pre-Shared Keys (PSKs) for TLS 1.3”, RFC 9258, DOI 10.17487/RFC9258, July 2022, <https://www.rfc-editor.org/info/rfc9258>.

10.2. Дополнительная литература

[AASS19] Akhmetzyanova, L., Alekseev, E., Smyshlyaeva, E., and A. Sokolov, “Continuing to reflect on TLS 1.3 with external PSK”, April 2019, <https://eprint.iacr.org/2019/421.pdf>.

[CPACE] Abdalla, M., Haase, B., and J. Hesse, “CPace, a balanced composable PAKE”, Work in Progress, Internet-Draft, draft-irtf-cfrg-cpace-06, 24 July 2022, <https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-cpace-06>.

[CTLS] Rescorla, E., Barnes, R., Tschofenig, H., and B. M. Schwartz, “Compact TLS 1.3”, Work in Progress, Internet-Draft, draft-ietf-tls-ctls-06, 9 July 2022, <https://datatracker.ietf.org/doc/html/draft-ietf-tls-ctls-06>.

[EAP-TLS-PSK] Mattsson, J. P., Sethi, M., Aura, T., and O. Friel, “EAP-TLS with PSK Authentication (EAP-TLS-PSK)”, Work in Progress, Internet-Draft, draft-mattsson-emu-eap-tls-psk-00, 9 March 2020, <https://datatracker.ietf.org/doc/html/draft-mattsson-emu-eap-tls-psk-00>.

[GAA] ETSI, “Digital cellular telecommunications system (Phase 2+); Universal Mobile Telecommunications System (UMTS); LTE; 3G Security; Generic Authentication Architecture (GAA); System description”, version 12.0.0, ETSI TR 133 919, October 2014, <https://www.etsi.org/deliver/etsi_tr/133900_133999/133919/12.00.00_60/tr_133919v120000p.pdf>.

[Krawczyk] Krawczyk, H., “SIGMA: The ‘SIGn-and-MAc’ Approach to Authenticated Diffie-Hellman and Its Use in the IKE Protocols”, DOI 10.1007/978-3-540-45146-4_24, 2003, <https://link.springer.com/content/pdf/10.1007/978-3-540-45146-4_24.pdf>.

[LwM2M] Open Mobile Alliance, “Lightweight Machine to Machine Technical Specification”, version 1.0, February 2017, <http://www.openmobilealliance.org/release/LightweightM2M/V1_0-20170208-A/OMA-TS-LightweightM2M-V1_0-20170208-A.pdf>.

[OPAQUE] Bourdrez, D., Krawczyk, H., Lewi, K., and C. A. Wood, “The OPAQUE Asymmetric PAKE Protocol”, Work in Progress, Internet-Draft, draft-irtf-cfrg-opaque-09, 6 July 2022, <https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-opaque-09>.

[RFC2865] Rigney, C., Willens, S., Rubens, A., and W. Simpson, “Remote Authentication Dial In User Service (RADIUS)”, RFC 2865, DOI 10.17487/RFC2865, June 2000, <https://www.rfc-editor.org/info/rfc2865>.

[RFC3748] Aboba, B., Blunk, L., Vollbrecht, J., Carlson, J., and H. Levkowetz, Ed., “Extensible Authentication Protocol (EAP)”, RFC 3748, DOI 10.17487/RFC3748, June 2004, <https://www.rfc-editor.org/info/rfc3748>.

[RFC4122] Leach, P., Mealling, M., and R. Salz, “A Universally Unique IDentifier (UUID) URN Namespace”, RFC 4122, DOI 10.17487/RFC4122, July 2005, <https://www.rfc-editor.org/info/rfc4122>.

[RFC4279] Eronen, P., Ed. and H. Tschofenig, Ed., “Pre-Shared Key Ciphersuites for Transport Layer Security (TLS)”, RFC 4279, DOI 10.17487/RFC4279, December 2005, <https://www.rfc-editor.org/info/rfc4279>.

[RFC6066] Eastlake 3rd, D., “Transport Layer Security (TLS) Extensions: Extension Definitions”, RFC 6066, DOI 10.17487/RFC6066, January 2011, <https://www.rfc-editor.org/info/rfc6066>.

[RFC6614] Winter, S., McCauley, M., Venaas, S., and K. Wierenga, “Transport Layer Security (TLS) Encryption for RADIUS”, RFC 6614, DOI 10.17487/RFC6614, May 2012, <https://www.rfc-editor.org/info/rfc6614>.

[RFC7925] Tschofenig, H., Ed. and T. Fossati, “Transport Layer Security (TLS) / Datagram Transport Layer Security (DTLS) Profiles for the Internet of Things”, RFC 7925, DOI 10.17487/RFC7925, July 2016, <https://www.rfc-editor.org/info/rfc7925>.

[RFC8773] Housley, R., “TLS 1.3 Extension for Certificate-Based Authentication with an External Pre-Shared Key”, RFC 8773, DOI 10.17487/RFC8773, March 2020, <https://www.rfc-editor.org/info/rfc8773>.

[RFC9147] Rescorla, E., Tschofenig, H., and N. Modadugu, “The Datagram Transport Layer Security (DTLS) Protocol Version 1.3”, RFC 9147, DOI 10.17487/RFC9147, April 2022, <https://www.rfc-editor.org/info/rfc9147>.

[Selfie] Drucker, N. and S. Gueron, “Selfie: reflections on TLS 1.3 with PSK”, DOI 10.1007/s00145-021-09387-y, May 2021, <https://eprint.iacr.org/2019/347.pdf>.

[Sethi] Sethi, M., Peltonen, A., and T. Aura, “Misbinding Attacks on Secure Device Pairing and Bootstrapping”, DOI 10.1145/3321705.3329813, May 2019, <https://arxiv.org/pdf/1902.07550>.

[SmartCard] Bundesamt für Sicherheit in der Informationstechnik, “Technical Guideline TR-03112-7 eCard-API-Framework – Protocols”, version 1.1.5, April 2015, <https://www.bsi.bund.de/SharedDocs/Downloads/DE/BSI/Publikationen/TechnischeRichtlinien/TR03112/TR-03112-api_teil7.pdf?__blob=publicationFile&v=1>.

Благодарности

Этот документ является результатом работы TLS External PSK Design Team, включающей Benjamin Beurdouche, Björn Haase, Christopher Wood, Colm MacCarthaigh, Eric Rescorla, Jonathan Hoyland, Martin Thomson, Mohamad Badra, Mohit Sethi, Oleg Pekar, Owen Friel, Russ Housley.

Документ был улучшен, благодаря высококачественным рецензиям Ben Kaduk и John Preuß Mattsson.

Адреса авторов

Russ Housley
Vigil Security, LLC
Email: housley@vigilsec.com
 
Jonathan Hoyland
Cloudflare Ltd.
Email: jonathan.hoyland@gmail.com
 
Mohit Sethi
Aalto University
Email: mohit@iki.fi
 
Christopher A. Wood
Cloudflare
Email: caw@heapingbits.net

Перевод на русский язык

Николай Малых

nmalykh@protokols.ru

1Internet Engineering Task Force – комиссия по решению инженерных задач Internet.

2Internet Engineering Steering Group – комиссия по инженерным разработкам Internet.

Рубрика: RFC | Оставить комментарий

RFC 9258 Importing External Pre-Shared Keys (PSKs) for TLS 1.3

image_print
Internet Engineering Task Force (IETF)                       D. Benjamin
Request for Comments: 9258                                  Google, LLC.
Category: Standards Track                                     C. A. Wood
ISSN: 2070-1721                                               Cloudflare
                                                               July 2022

Importing External Pre-Shared Keys (PSKs) for TLS 1.3

Импорт внешних ключей PSK для TLS 1.3

PDF

Аннотация

Этот документ описывает интерфейс для импорта внешних заранее распространённых ключей (Pre-Shared Key или PSK) в TLS 1.3.

Статус документа

Документ относится к категории Internet Standards Track.

Документ является результатом работы IETF1 и представляет согласованный взгляд сообщества IETF. Документ прошёл открытое обсуждение и был одобрен для публикации IESG2. Дополнительную информацию о стандартах Internet можно найти в разделе 2 в RFC 7841.

Информация о текущем статусе документа, найденных ошибках и способах обратной связи доступна по ссылке https://www.rfc-editor.org/info/rfc9258.

Авторские права

Copyright (c) 2022. Авторские права принадлежат IETF Trust и лицам, указанным в качестве авторов документа. Все права защищены.

К документу применимы права и ограничения, указанные в BCP 78 и IETF Trust Legal Provisions и относящиеся к документам IETF (http://trustee.ietf.org/license-info), на момент публикации данного документа. Прочтите упомянутые документы внимательно. Фрагменты программного кода, включённые в этот документ, распространяются в соответствии с упрощённой лицензией BSD, как указано в параграфе 4.e документа IETF Trust Legal Provisions, без каких-либо гарантий (как указано в Simplified BSD License).

Оглавление

Исключено в версии HTML.

1. Введение

TLS 1.3 [RFC8446] поддерживает аутентификацию с заранее распределенным ключом (PSK), при этом ключи PSK могут устанавливаться с помощью сеансовых квитанций (ticket) из предшествующих соединений или с помощью специального (out-of-band) механизма. Протокол требует, чтобы каждый ключ PSK использовался лишь с одной хэш-функцией. Это сделано для упрощения анализа протокола. В TLS 1.2 [RFC5246] такого требования нет и PSK может применяться с любым алгоритмом хэширования и псевдослучайной функцией (pseudorandom function или PRF) TLS 1.2. Хотя не известно способа, каким один и тот же внешний PSK может давать связанный вывод в TLS 1.3 и предшествующих версиях, был проведён лишь ограниченный анализ. Приложениям следует предоставлять раздельные PSK для (О)TLS 1.3 и прежних версий. Если это невозможно (например, внешние PSK уже развёрнуты или имеются иные ограничения), повторное использование PSK в разных версиях TLS может давать связанный вывод, который, в свою очередь, ведёт к проблемам безопасности (см. Приложение E.7 к [RFC8446]).

Для смягчения проблем этот документ задаёт интерфейс импортёра PSK. С помощью которого можно импортировать внешние PSK и потом привязать их к конкретной функции вывода ключей (key derivation function или KDF) и хэш-функции для использования в TLS 1.3 [RFC8446] и DTLS 1.3 [RFC9147]. В частности, описывается механизм для импорта PSK, выведенных из внешних PSK путём включения целевой KDF, версии протокола (D)TLS и необязательной строки контекста для обеспечения уникальности. Этот процесс даёт набор PSK-кандидатов, каждый из которых привязан к целевой KDF и протоколу, которые отличаются от применяемых в (D)TLS 1.2 и прежних версий. Это преобразует отдельный PSK и отождествление в набор PSK и отождествлений.

2. Принятые соглашения

Ключевые слова необходимо (MUST), недопустимо (MUST NOT), требуется (REQUIRED), нужно (SHALL), не нужно (SHALL NOT), следует (SHOULD), не следует (SHOULD NOT), рекомендуется (RECOMMENDED), не рекомендуется (NOT RECOMMENDED), возможно (MAY), необязательно (OPTIONAL) в данном документе должны интерпретироваться в соответствии с BCP 14 [RFC2119] [RFC8174] тогда и только тогда, когда они выделены шрифтом, как показано здесь.

3. Терминология

Ниже приведены определения используемых в документе терминов.

External PSK (EPSK) – внешний PSK

Ключ PSK организованный или предоставленный внешними средствами (out of band), т. е не в соединении TLS, который представляет собой кортеж (Base Key, External Identity, Hash).

Base Key – базовый ключ

Секретное значение EPSK.

External Identity – внешнее отождествление (свидетельство)

Последовательность байтов, служащая для идентификации EPSK.

Target protocol – целевой протокол

Протокол, для которого импортируется PSK.

Target KDF – целевая KDF

Функция KDF, для которой импортируется PSK.

Imported PSK (IPSK) – импортированный PSK

Ключ TLS PSK выведенный из EPSK, необязательной строки контекста, целевого протокола и целевой KDF.

Non-imported PSK – неимпортированный PSK

Ключ EPSK, испольуемый в качестве TLS PSK напрямую (без импорта).

Imported Identity – импортированное отождествление

Последовательность байтов, служащая для идентификации IPSK.

В документе применяется язык представления из раздела 3 в [RFC8446].

4. Обзор

Интерфейс импортёра PSK отражает интерфейс экспортёра TLS (см. [RFC8446]) в том смысле, что он меняет ключ на основе некоторой контекстной информации. В отличие от интерфейса экспортёра, где уникальность вывода достигается за счёт явной метки и строки контекста, определённый здесь интерфейс импортёра принимает внешний ключ PSK и отождествление, «импортируя» их в TLS путём создания набора «производных» PSK и отождествлений, которые уникальны. Каждый из этих выведенных PSK привязывается к целевому протоколу, идентификатору KDF и необязательной строке контекста. Кроме того, полученные ключи изменяются с использованием новой метки вывода для предотвращения конфликтов с неимпортированными PSK. Через этот интерфейс импорт внешних PSK с разными отждествлениями даёт разные ключи привязки PSK (binder).

Использование импортированных ключей не требуется согласовывать, поскольку клиент и сервер не согласуют отождествления, если импорт был некорректен. Конечные точки могут постепенно развёртывать поддержку импортёров PSK, предлагая неимпортированные PSK для TLS версий до TLS 1.3. Неимпортированные и импортированные PSK не эквивалентны, поскольку из отождествления различаются (см. раздел 7).

Конечным точкам, импортирующим внешние ключи, недопустимо применять служащие вводом в процесс импорта ключи для каких-либо иных целей и недопустимо применять выведенные ключи для целей, отличных от TLS PSK. Кроме того, каждый внешний PSK, введенный в процесс импортёра, должен быть связан не более чем с одной хэш-функцией. Это аналогично правилам параграфа 4.2.11 [RFC8446]. Дополнительное обсуждение приведено в разделе 8.

5. Импортёр PSK

В этом разделе описан интерфейс импортёра PSK и лежащий в его основе механизм диверсификации, а также изменение расчёта связующего ключа (binder key).

5.1. Диверсификация внешнего PSK

На входе интерфейс импортёра PSK принимает EPSK с внешним отождествлением (External Identity) external_identity и базовым ключом epsk (определены в разделе 3) вместе с необязательным контекстом. Затем ввод преобразуется в набор PSK и импортированных отождествлений для использования в соединении с целевым протоколом и KDF. В частности, для каждого поддерживаемого целевого протокола target_protocol и KDF target_kdf импортёр создаёт структуру ImportedIdentity, показанную ниже.

   struct {
      opaque external_identity<1...2^16-1>;
      opaque context<0..2^16-1>;
      uint16 target_protocol;
      uint16 target_kdf;
   } ImportedIdentity;

Список значений ImportedIdentity.target_kdf поддерживается IANA, как указано в разделе 10. Внешние PSK недопустимо импортировать для (D)TLS 1.2 и более ранних версий. В разделе 7 обсыждается сосуществование импортированных PSK для TLS 1.3 с неимпортированными PSK более ранних версий при поэтапном развертывании.

Значение ImportedIdentity.context должно включать контекст, используемый для определения EPSK, если тот имеется. Например, ImportedIdentity.context может включать сведения о ролях партнёров или отождествления для смягчения атак с отражением в стиле Selfie (Selfie-style reflection attack) [Selfie] (см. Приложение A). Поскольку EPSK является ключом, выведенным из внешнего протокола или последовательности протоколов, значение ImportedIdentity.context должно включать привязку каналов для производных протоколов [RFC5056]. Детали этой привязки зависят от протокола и выходят за рамки этой спецификации.

Значение ImportedIdentity.target_protocol должно указывать версию протокола (D)TLS, для которой импортируется PSK. Например, TLS 1.3 [RFC8446] использует значение 0x0304, которое применяется также в QUICv1 [QUIC]. Отметим, что это означает зависимость числа PSK, выводимых из EPSK, от числа целевых протоколов.

На основе ImportedIdentity и соответствующего EPSK с базовым ключом epsk, импортированный PSK IPSK с базовым ключом ipskx вычисляется, как показано ниже.

epskx = HKDF-Extract(0, epsk)
ipskx = HKDF-Expand-Label(epskx, "derived psk", Hash(ImportedIdentity), L)

L соответствует размеру вывода KDF ImportedIdentity.target_kdf, как указано в разделе 10. Для основанных на хэшировании KDF, таких как HKDF_SHA256 (0x0001), это будет размер результата хэш-функции, например, 32 октета для SHA256. Ключ IPSK должен иметь размер, подхожящий для поддерживаемых шифров. Внутри HKDF-Expand-Label применяет метку, соответствующую ImportedIdentity.target_protocol (например, “tls13” для TLS 1.3 в соответствии с параграфом 7.1 [RFC8446] или “dtls13” для DTLS 1.3 в соответствии с параграфом Section 5.10 [RFC9147]).

Отождествлением ipskx при передаче в линию служит ImportedIdentity, т. е. преобразованное в последовательную форму содержимое ImportedIdentity выступает как содержимое PskIdentity.identity в расширении PSK. Соответствующим вводом PSK для планирования ключей TLS 1.3 является “ipskx”.

Поскольку максимальный размер расширения PSK составляет 216 – 1 октетов, импортированное отождествление (Imported Identity), превышающее этот размер, может вызывать ошибку декодирования. Поэтому интерфейсу импортёра PSK следует отвергать ImportedIdentity с размером, превышающим это значение.

Хэш-функция, используемая для функции вывода ключей на основе HMAC (HMAC-based Key Derivation Function или HKDF) [RFC5869], связана с EPSK. Это не хэш-функция, связанная с ImportedIdentity.target_kdf. Если EPSK не имеет связанной хэш-функции, следует применять SHA-256 [SHA2]. Диверсификация EPSK с помощью ImportedIdentity.target_kdf гарантирует, что IPSK применяется в качестве входного ключевого материала KDF не более 1 раза, что соответствует требованиям [RFC8446] (см. раздел 8).

Конечным точкам следует генерировать совместимые отождествления ipskx для каждого целевого шифра, который точка поддерживает. Например, импорт ключей для TLS_AES_128_GCM_SHA256 и TLS_AES_256_GCM_SHA384 будет давать два PSK, один для HKDF-SHA256, другой для HKDF-SHA384. При поддержке TLS_AES_128_GCM_SHA256 и TLS_CHACHA20_POLY1305_SHA256, напротив, нужен лишь 1 производный ключ. Каждый шифр однозначно указывает целевую функцию KDF. Будущие спецификации, меняющие способ согласования KDF, должны будут обновить эту спецификацию для разъяснения выбора целевых KDF в процессе импорта.

EPSK можно импортировать до начала соединения, если целевые KDF, протоколы и строки контекста известны заранее. Можно также импортировать EPSK для упреждающего использования данных, если они привязаны к настройкам протокола и конфигурации, которые требуются для упреждающей передачи данных. По минимуму это означает, что вместе с EPSK должны быть предоставлены значение согласования протокола прикладного уровня (Application-Layer Protocol Negotiation или ALPN) [RFC7301], транспортные параметры QUIC (при использовании с QUIC) и другие связанные параметры, согласуемые для упреждающих данных.

5.2. Вывод связующего ключа

Для предотвращения путаницы между импортированными и неимпортированными PSK в импортированных PSK меняется метка вывода связующего ключа PSK. В частности, вычисление стандартного связующего ключа TLS 1.3 PSK выполняется, как показано ниже.

              0
              |
              v
    PSK ->  HKDF-Extract = Early Secret
              |
              +-----> Derive-Secret(., "ext binder" | "res binder", "")
              |                     = binder_key
              V

Импортированные PSK при выводе binder_key используют строку “imp binder” вместо “ext binder” или “res binder” и расчёт связующего ключа имеет вид

              0
              |
              v
    PSK ->  HKDF-Extract = Early Secret
              |
              +-----> Derive-Secret(., "ext binder"
              |                      | "res binder"
              |                      | "imp binder", "")
              |                     = binder_key
              V

Эта новая метка гарантирует, что клиент и сервер будут согласовывать применение внешнего PSK тогда и только тогда, когда (a) обе конечные точки импортируют PSK или (b) ни одна из них не делает этого. Поскольку binder_key является ключом листа, изменение расчёта не влияет на другие ключи.

6. Отмена хэш-функций

Клиент или сервер, желающий отменить хэш-функцию и больше не применять её для TLS 1.3, удаляет соответствующую KDF из числа целевых KDF при импорет ключей. Это не влияет на работу KDF, служащих для вывода импортируемых PSK.

7. Постепенное развёртывание

В системах, где PSK уже подготовлены для применения с TLS 1.2, попытка поэтапного развёртывания механизма импорта приведёт к одновременному использованию уже предоставленных PSK напрямую как TLS 1.2 PSK и как EPSK, что, в свою очередь, означает возможность применения одних KDF и ключа а двух разных контекстах протокола. Это не рекомендуется (см. раздел 8). Однако преимущества применения TLS 1.3 и импортёров PSK могут быть достаточно убедительными для выбора в существующем развёртывании такой несовместимой конфигурации на короткий период развёртывания новых программ (использующих TLS 1.3 и импортёры). Операторам рекомендуется делать этот период как можно короче.

8. Вопросы безопасности

Цель безопасности импортёра PSK можно грубо сформулировать как предотвращение повторного применения PSK в KDF при надлежащей аутентификации конечных точек. При моделировании в качестве вычислительных экстракторов KDF предполагают, что входной ключевой материал (input keying material или IKM) отбирается из некого «источника» распределения вероятности и любые два значения IKM выбирабтся независимо одно от другого [Kraw10]. Это требование независимости от источника предполагает, что одно значение IKM не может применяться в разных KDF.

Аутентификация на базе PSK функционально эквивалентна возобновлению сессии, поскольку соединение применяет имеющийся ключевой материал для аутентификации обеих конечных точек. В соответствии с [BAA15] это является формой композитной аутентификации. Такая аутентификация, грубо говоря, является свойством, состоящим в том, что выполнение нескольких протоколов аутентификации, из которых хотя бы 1 не скомпрометирован, совместно аутентифицирует все протоколы. Поэтому аутентификации с предоставленными извне PSK в идеале следует аутентифицировать как соединение TLS, так и внешний процесс представления. Обычно этот процесс создаёт PSK и соответствующий контекст, где PSK был выведен и где его следует применять. При доступности контекст используется как значение ImportedIdentity.context. Внешний PSK без такого контекста называется безконтекстным (context-free).

Таким образом, с учётом требований независимости от источника и составной аутентификации описанный в документе интерфейс импортёра PSK направлен на достижение указанных ниже целей.

  1. Импорт предоставленных извне PSK в соединение TLS обеспечивает составную аутентификацию соединения и процесса представления.

  2. Безконтекстные PSK обеспечивают аутентификацию лишь в контексте одного соединения.

  3. Импортированные PSK не применяются в качестве IKM для двух разных KDF.

  4. Импортированные PSK не будут конфиликтовать с будущими версиями протокола и функций KDF.

Нет каких-либо известных данных или проблем безопасности, вызываемых процессом расчёта импортируемых PSK из внешниз PSK и обработки имеющихся внешних PSK, применяемых в (D)TLS 1.2 и ниже, как указано в разделе 7. Однако был проведён лишь ограниченный анализ и это является ещё одной причиной, почему приложениям следует предоствалять отдельные PSK для (D)TLS 1.3 и прежних версий даже с интерфейсом импортёра (D)TLS 1.3.

Импортёр PSK не предотвращает создание приложениями отождествлений PSK без импорта, конфликтующих с импортированными отождествлениями PSK.

9. Вопросы приватности

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

Отметим, что ImportedIdentity.context является открытым текстом в линии как часть отождествления PSK. Без защиты механизмами вроде TLS Encrypted ClientHello [ECH] приложениям не следует помещать в это поле приватные данные.

10. Взаимодействие с IANA

Агентство IANA создало реестр TLS KDF Identifiers в имеющемся реестре Transport Layer Security (TLS) Parameters. Записи реестра показаны в таблице 1

Таблица 1. Реестр идентификаторов TLS KDF.

 

Значение

Описание KDF

Документ

0x0000

Резерв

RFC 9258

0x0001

HKDF_SHA256

[RFC5869]

0x0002

HKDF_SHA384

[RFC5869]

 

Новые значения для целевых KDF выделяются в соответствии с указанными ниже процедурами:

  • для диапазона 0x0000-0xfeff применяется процедура Specification Required [RFC8126];

  • значения 0xff00-0xffff зарезервированы для приватного использования (Private Use) [RFC8126].

Процедуры регистрации значений в пространстве Specification Required заданы в разделе 17 [RFC8447].

11. Литература

11.1. Нормативные документы

[RFC2119] Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels”, BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, <https://www.rfc-editor.org/info/rfc2119>.

[RFC5056] Williams, N., “On the Use of Channel Bindings to Secure Channels”, RFC 5056, DOI 10.17487/RFC5056, November 2007, <https://www.rfc-editor.org/info/rfc5056>.

[RFC5869] Krawczyk, H. and P. Eronen, “HMAC-based Extract-and-Expand Key Derivation Function (HKDF)”, RFC 5869, DOI 10.17487/RFC5869, May 2010, <https://www.rfc-editor.org/info/rfc5869>.

[RFC8126] Cotton, M., Leiba, B., and T. Narten, “Guidelines for Writing an IANA Considerations Section in RFCs”, BCP 26, RFC 8126, DOI 10.17487/RFC8126, June 2017, <https://www.rfc-editor.org/info/rfc8126>.

[RFC8174] Leiba, B., “Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words”, BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, <https://www.rfc-editor.org/info/rfc8174>.

[RFC8446] Rescorla, E., “The Transport Layer Security (TLS) Protocol Version 1.3”, RFC 8446, DOI 10.17487/RFC8446, August 2018, <https://www.rfc-editor.org/info/rfc8446>.

[RFC8447] Salowey, J. and S. Turner, “IANA Registry Updates for TLS and DTLS”, RFC 8447, DOI 10.17487/RFC8447, August 2018, <https://www.rfc-editor.org/info/rfc8447>.

[RFC9147] Rescorla, E., Tschofenig, H., and N. Modadugu, “The Datagram Transport Layer Security (DTLS) Protocol Version 1.3”, RFC 9147, DOI 10.17487/RFC9147, April 2022, <https://www.rfc-editor.org/info/rfc9147>.

11.2. Дополнительная литература

[BAA15] Bhargavan, K., Delignat-Lavaud, A., and A. Pironti, “Verified Contributive Channel Bindings for Compound Authentication”, Proceedings 2015 Network and Distributed System Security, DOI 10.14722/ndss.2015.23277, February 2015, <https://doi.org/10.14722/ndss.2015.23277>.

[ECH] Rescorla, E., Oku, K., Sullivan, N., and C. A. Wood, “TLS Encrypted Client Hello”, Work in Progress, Internet-Draft, draft-ietf-tls-esni-14, 13 February 2022, <https://datatracker.ietf.org/doc/html/draft-ietf-tls-esni-14>.

[Kraw10] Krawczyk, H., “Cryptographic Extraction and Key Derivation: The HKDF Scheme”, Proceedings of Crypto 2010, May 2010, <https://eprint.iacr.org/2010/264>.

[QUIC] Iyengar, J., Ed. and M. Thomson, Ed., “QUIC: A UDP-Based Multiplexed and Secure Transport”, RFC 9000, DOI 10.17487/RFC9000, May 2021, <https://www.rfc-editor.org/info/rfc9000>.

[RFC5246] Dierks, T. and E. Rescorla, “The Transport Layer Security (TLS) Protocol Version 1.2”, RFC 5246, DOI 10.17487/RFC5246, August 2008, <https://www.rfc-editor.org/info/rfc5246>.

[RFC7301] Friedl, S., Popov, A., Langley, A., and E. Stephan, “Transport Layer Security (TLS) Application-Layer Protocol Negotiation Extension”, RFC 7301, DOI 10.17487/RFC7301, July 2014, <https://www.rfc-editor.org/info/rfc7301>.

[Selfie] Drucker, N. and S. Gueron, “Selfie: reflections on TLS 1.3 with PSK”, DOI 10.1007/s00145-021-09387-y, May 2021, <https://eprint.iacr.org/2019/347.pdf>.

[SHA2] National Institute of Standards and Technology, “Secure Hash Standard (SHS)”, FIPS PUB 180-4, DOI 10.6028/NIST.FIPS.180-4, August 2015, <https://doi.org/10.6028/NIST.FIPS.180-4>.

Приложение A. Атаки Selfie

Атаки Selfie [Selfie] основаны на злоупотреблении интерфейсом PSK, неявно предполагающим, что каждый ключ PSK известен лишь клиенту и серверу. Если несколько клиентов или серверов с разными ролями используют общий ключ PSK, TLS аутентифицирует лишь группу целиком. Узел аутентифицирует своего партнёра из группы независимо от подлинности того. Отметим, что такое возможно и в случае совместного применения PSK двумя узлами без ролей.

Приложения, требующие аутентификации по ролям при использовании общего PSK для всех узлов, могут решить проблему путём передачи сведений о ролях через соединение TLS после согласования или путём включения роли клиента и сервера в строку контекста IPSK. Например, если приложение идентифицирует каждый узел по MAC-адресу (Media Access Control), оно может использовать приведённую ниже строку контекста.

     struct {
       opaque client_mac<0..2^8-1>;
       opaque server_mac<0..2^8-1>;
     } Context;

Если злоумышленник затем переправит сообщение ClientHello, предназначенное одному узлу, на другой узел, включая создателя ClientHello, получатель определит другую строку контекста и согласование не завершится успехом.

Отметим, что в этом варианте по=прежнему применяется один общий ключ PSK для всех узлов поэтому каждый узел должен быть доверенным, чтобы он не взял на себя чужую роль (прикинулся другим узлом).

Благодарности

Авторы признательны Eric Rescorla и Martin Thomson за дискуссии, которые привели к созданию этого документа, а также Christian Huitema за вклад в соображения по приватности внешних PSK. John Preuß Mattsson предоставил сведения по части развёртывания импортёров PSK. Hugo Krawczyk предоставил рекомендации по безопасности. Martin Thomson, Jonathan Hoyland, Scott Hollenbeck, Benjamin Kaduk и другие предоставили рецензии, отклики и предложения по улучшению документа.

Адреса авторов

David Benjamin
Google, LLC.
Email: davidben@google.com
 
Christopher A. Wood
Cloudflare
Email: caw@heapingbits.net

Перевод на русский язык

Николай Малых

nmalykh@protokols.ru

1Internet Engineering Task Force – комиссия по решению инженерных задач Internet.

2Internet Engineering Steering Group – комиссия по инженерным разработкам Internet.

Рубрика: RFC, Безопасность | Оставить комментарий

RFC 9254 Encoding of Data Modeled with YANG in the Concise Binary Object Representation (CBOR)

image_print
Internet Engineering Task Force (IETF)                 M. Veillette, Ed.
Request for Comments: 9254                       Trilliant Networks Inc.
Category: Standards Track                                 I. Petrov, Ed.
ISSN: 2070-1721                                  Google Switzerland GmbH
                                                                A. Pelov
                                                                  Acklio
                                                              C. Bormann
                                                  Universität Bremen TZI
                                                           M. Richardson
                                                Sandelman Software Works
                                                               July 2022

Encoding of Data Modeled with YANG in the Concise Binary Object Representation (CBOR)

Кодирование данных модели YANG в CBOR

PDF

Аннотация

Язык моделирования данных YANG (RFC 7950) служит для моделирования данных конфигурации и состояния, параметров и результатов вызовов удалённых процедур (Remote Procedure Call или RPC) или действий и уведомлений.

Этот документ определяет представление правил YANG в CBOR (Concise Binary Object Representation) (RFC 8949).

Статус документа

Документ относится к категории Internet Standards Track.

Документ является результатом работы IETF1 и представляет согласованный взгляд сообщества IETF. Документ прошёл открытое обсуждение и был одобрен для публикации IESG2. Дополнительную информацию о стандартах Internet можно найти в разделе 2 в RFC 7841.

Информация о текущем статусе документа, найденных ошибках и способах обратной связи доступна по ссылке https://www.rfc-editor.org/info/rfc9254.

Авторские права

Copyright (c) 2022. Авторские права принадлежат IETF Trust и лицам, указанным в качестве авторов документа. Все права защищены.

К документу применимы права и ограничения, указанные в BCP 78 и IETF Trust Legal Provisions и относящиеся к документам IETF (http://trustee.ietf.org/license-info), на момент публикации данного документа. Прочтите упомянутые документы внимательно. Фрагменты программного кода, включённые в этот документ, распространяются в соответствии с упрощённой лицензией BSD, как указано в параграфе 4.e документа IETF Trust Legal Provisions, без каких-либо гарантий (как указано в Simplified BSD License).

Оглавление

Исключено в версии HTML

1. Введение

Спецификация языка моделирования данных YANG 1.1 [RFC7950] определяет представление XML для экземпляров данных, т. е. содержимого хранилищ конфигурации, данных состояния, ввода и вывода RPC и действий, уведомлений о событиях. Дополнительный набор правил кодирования задан в [RFC7951] на основе The JavaScript Object Notation (JSON) Data Interchange Format” [RFC8259].

Целью этого документа является задание набора правил кодирования для краткого представления двоичных объектов (Concise Binary Object Representation или CBOR) [RFC8949], называемого YANG-CBOR. Задаваемое кодирование компактней XML и JSON и более подходит для узлов и/или сетей с ограничениями, описанных в [RFC7228].

2. Терминология и нотация

Ключевые слова необходимо (MUST), недопустимо (MUST NOT), требуется (REQUIRED), нужно (SHALL), не нужно (SHALL NOT), следует (SHOULD), не следует (SHOULD NOT), рекомендуется (RECOMMENDED), не рекомендуется (NOT RECOMMENDED), возможно (MAY), необязательно (OPTIONAL) в данном документе должны интерпретироваться в соответствии с BCP 14 [RFC2119] [RFC8174] тогда и только тогда, когда они выделены шрифтом, как показано здесь.

Значения SID (и рассчитанные по ним детали SID) показаны в примерах лишь для иллюстрации.

Ниже перечислены термины, определённые в [RFC7950].

  • action – действие;

  • anydata – любые данные;

  • anyxml – любые данные XML;

  • data node – узел данных;

  • data tree – дерево данных;

  • datastore – хранилище данных;

  • feature – функция, возможность;

  • identity – отождествление

  • module – модуль;

  • notification – уведомление;

  • RPC – удаленный вызов процедуры;

  • schema node – узел схемы;

  • submodule – субмодуль.

В [RFC8040] определён термин

  • yang-data extension – расширение yang-data.

В [RFC8791] определён термин

  • YANG data structure – структура данных YANG.

Эта спецификация использует также определённые ниже термины.

YANG Schema Item iDentifier (YANG SID или SID) – идентификатор элемента схемы YANG

63-битовое целое число без знака, служащее для идентификации элемента YANG.

delta – приращение

Разница между текущим и эталонным значением YANG SID. Эталон YANG SID определён в каждом контексте, где применяется приращение.

absolute SID – абсолютный SID

Значение YANG SID, не представляемое приращением. Обычно идентификатор называется явно только в позиции, где обычно можно найти приращение.

representation tree – дерево представления

Дерево данных YANG, возможно заключённое в узел схемы, такое как структура данных YANG, уведомление, RPC, действие.

representation node – узел представления

Узел в дереве представления, т. е. узел дерева данных, или представление узла схемы, такое как структура данных YANG, уведомление, RPC, действие.

item – элемент

Узел схемы, отождествление, модуль или свойство, определённые с использованием языка моделирования YANG.

list entry – запись списка

данные, связанные с одной записью в списке (см. параграф 7.8 в [RFC7950]).

container-like instance – контейнероподобный экземпляр

Экземпляр контейнера, структура данных YANG, содержимое уведомления, ввод или вывод RPC или действия (параграф 4.2), запись в списке (параграф 4.4), узел anydata (параграф 4.5).

parent (of a representation node) – родитель узла представления

Узел схемы ближайшего охватывающего узла представления, в котором определён данный узел представления.

3. Свойства кодирования CBOR

Этот документ задаёт правила кодирования CBOR для деревьев данных YANG и их субдеревьев.

Дерево данных YANG может помещаться в представление узла схемы, такое как структура данных YANG, уведомление, RPC или действие, это называется деревом представления. Узлы дерева данных и представление узла схемы, включающего дерево, совместно называют узлами представления (representation node).

Узел представления, такой как контейнер, записи списка, структура данных YANG, уведомление, ввод или вывод RPC или действия, узел anydata, сериализуется с использованием отображения CBOR, где каждый определённый узел схемы кодируется ключом и значением. Эта спецификация поддерживает два типа ключей CBOR – идентификаторы YANG SID (YANG Schema Item iDentifier), определённые в параграфе 3.2, и имена, как указано в параграфе 3.3. Каждый из этих типов ключей кодируется с применением конкретного типа CBOR, что позволяет интерпретировать их в процессе десериализации. Протоколы и механизмы, реализующие эту спецификацию, могут предписывать применение определённого типа ключей или разрешать генератору свободный выбор для каждого ключа.

Для минимизации размера закодированных данных отображение избегает всей необязательной метаинформации, сверх представленной напрямую базовой моделью данных CBOR (раздел 2 в [RFC8949]). Например, теги CBOR применяются лишь для абсолютных SID, узлов данных anyxml и типа данных union, чтобы явно различать типы данных YANG, закодированные с использованием одного базового типа CBOR.

Если иное явно не указано в протоколе или механизме, реализующем эту спецификацию, нужно поддерживать в декодерах CBOR, реализующих YANG-CBOR, кодирование неопределённого размера, определённое в параграфе 3.2 [RFC8949]. Это позволяет реализации начинать выдачу массива или отображения до того, как станет известно точное число элементов, а также, возможно, предотвратить неоправданные блокировки и конкуренцию. С другой стороны, это лишает получателя кодированных данных возможности заранее аносировать сведения о размере, когда эти преимущества действительно возникают.

Узлы данных, реализованные с применением массивов, отображения, строк байтов или текста CBOR, могут создаваться пустыми. В этом случае они кодируются с нулевым размером.

При сериализации узлов представления по заданным этой спецификацией правилам как части данных (payload) приложения в эти данные следует включать сведения об узлах, позволяющие идентифицировать узлы без хранения состояний, например, связанный с узлом номер SID, приращение SID от другого SID в данных приложения, имя с указанием пространства имён, идентификатор экземпляра.

Примеры в разделе 4 включают корневое отображение CBOR с одной записью, имеющей в качестве ключа имя с указанием пространства имён или SID. Эти корневые отображения CBOR представлены лишь в качестве примеров использования и не являются частью правил кодирования. Обязательным является лишь значение в этом отображении CBOR.

3.1. Диагностическая нотация CBOR

В этом документе двоичное содержимое CBOR представляется с использованием эквивалентной текстовой формы, называемой диагностической нотацией CBOR, как определено в разделе 8 [RFC8949]. Эта нотация служит лишь для документации и не применяется при сериализации данных. Сводка нотации представлена в таблице 1.

Таблица 1. Сводка диагностической нотации CBOR.

Содержимое CBOR

Тип CBOR

Диагностическая нотация

Пример

Код CBOR

Целое число без знака

0

Десятичные цифры

123

18 7B

Отрицательное целое число

1

Десятичные цифры со знаком минус (-)

-123

38 7A

Строка байтов

2

Шестнадцатеричное значение в одинарных кавычках или с префиксом h

h’F15C’

42 F15C

Строка текста

3

Строка символов Unicode в двойных кавычках

“txt”

63 747874

Массив

4

Список значений через запятую, заключённых в квадратные скобки

[ 1, 2 ]

82 01 02

Отображение

5

Список пар ключ-значение через запятую, заключённых в фигурные скобки

{ 1: 123, 2: 456 }

A2 01187B 021901C8

Логическое значение

7/20
7/21

false
true

false
true

F4
F5

Null

7/22

null

null

F6

Не выделено

7/23

undefined

undefined

F7

Примечание. Двоичное содержимое CBOR в этой спецификации сопровождается комментариями, обозначенными символами /, как указано в Приложении G.6 [RFC8610].

3.2. Идентификатор элемента схемы YANG

Некоторые из элементов YANG [RFC7950] требуют применения уникального идентификатора. В протоколах настройки конфигурации сети (Network Configuration Protocol или NETCONF) [RFC6241] и RESTCONF [RFC8040] такими идентификаторами служат строки текста. Для обеспечения реализации моделей данных, определённых в YANG, устроствами или сетями с ограничениями нужен более компактный метод идентификации элементов YANG. Такой компактный идентификатор называется идентификатором элемента схемы YANG (YANG Schema Item iDentifier) и является 63-битовым целым числом без знака (0..9223372036854775807 или 0..0x7fffffffffffffff). Ниже указаны элементы, идентифицируемые с помощью YANG SID (или просто SID).

  • Отождествления;

  • узлы данных,

  • RPC и связанные с ними ввод и вывод;

  • действия и связанные с ними ввод и вывод;

  • структуры данных YANG;

  • уведомления и связанная с ними информация;

  • модули и функции (feature) YANG.

Отметим, что любое структурирование модулей по субмодулям не заметно для YANG-CBOR, SID не выделяются для имён субмодулей и любые элементы внутри субмодуля фактически получают SID при обработке содержащего их модуля.

Для минимизации размера SID, применяемые как ключи в отображениях CBOR кодируются с использованием приращения целыми числами со знаком, которые складываются с эталонным SID для отображения. Эталонный SID внешнего отображения имеет значение 0, если другой эталонный SID не задан однозначно из среды, где применяется внешнее отображение. Эталонный SID отображения, напрямую встроенного в запись отображения с ключом на основе имени имеет значение 0. Для прочих отображений эталонным SID является значение, рассчитанное для записи отображения, в которую оно встроено напрямую (встраивание может быть опосредованным, если применяется массив, например, в списке YANG). Там, где желательны абсолютные SID (целое число предполагает приращение), они должны указываться абсолютными значениями SID с использованием тега CBOR 47 (как указано в параграфе 4.2.1).

Таким образом, преобразование SID в приращение и обратно не использует состояния и основано исключительно на (де)сериализованных данных, возможно в комбинации с эталонным внешним SID, однозначно заданным средой.

Механизмы и процессы назначения SID элементам YANG и обеспечения их уникальности выходят за рамки этой спецификации. Если нужно применять SID, эта спецификация используется вместе со спецификацией, определяющей управление идентификаторами. Связанный документ [CORE-SID] предназначен для указания способа назначения SID для модулей YANG, поддерживаемых IETF, и рекомендуется для остальных модулей YANG. Данная спецификация разработана для поддержки разных методов назначения в отдельных доменах (областях).

Для предоставления реализациям способа внутренней индикации отсутствия SID значение SID = 0 зарезервировано и не будет выделяться. Оно не применяется при обмене.

3.3. Имя

Эта спецификация поддерживает также представление идентификаторов элементов YANG строками текста, подобно принятому в JSON кодированию данных моделей [RFC7951]. Такой подход может избавить от издержек, связанных с выделением SID. Основным недостатком этого подхода является рост размера закодированих данных.

Идентификаторы элементов YANG по именам должны иметь одну из двух форма:

  • простой (simple) идентификатор элемента YANG (узла схемы или отождествления);

  • заданный с пространством имён (namespace-qualified) идентификатор элемента YANG с префиксом в виде имени модуля, где определён элемент, отделённым двоеточием (:).

Имя модуля задаёт пространство имён для всех элементов YANG, определённых в этом модуле. Если элемент задан в субмодуле, полное имя (с пространством имён) использует имя основного модуля, к которому относится субмодуль.

Синтаксис ABNF [RFC5234] для имени показан на рисунке 1, а создание identifier определено в разделе 14 [RFC7950].

   name = [identifier ":"] identifier

Рисунок 1. Вывод ABNF для простого имени или имени с пространством имён.


Полное (namespace-qualified) имя должно применяться для всех элементов верхнего уровня в отображении CBOR, а также во всех случаях, когда пространства имён узла представления и его родителя различаются. В остальных случаях должны использоваться простые имена.

Пример определения

   module example-foomod {
     container top {
       leaf foo {
         type uint8;
       }
     }
   }

   module example-barmod {
     import example-foomod {
       prefix "foomod";
     }
     augment "/foomod:top" {
       leaf bar {
         type boolean;
       }
     }
   }

Действительное кодирование CBOR для контейнера top показано ниже.

Диагностическая нотация CBOR

   {
     "example-foomod:top": {
       "foo": 54,
       "example-barmod:bar": true
     }
   }

Контейнер top и лист bar, определенные в другом модуле YANG как в родительском контейнере, кодируются с полными именами. Лист foo определён в том же модуле YANG, что и его родительский контейнер, кодируется простым именем.

4. Кодирование узлов представления

Узлы представления, определённые с использованием языка моделирования YANG, кодируются с применением CBOR [RFC8949] по правилам, заданным в этом разделе. Предполагается, что читатель знаком с YANG [RFC7950] и CBOR [RFC8949].

4.1. leaf

Кодирование leaf должно выполняться в соответствии с типом данных листа на основе одного из правил раздела 6.

Приведённые ниже примеры, взятые из [RFC6991] и [RFC7317], демонстрируют кодирование листа hostname с применением SID или имени.

   typedef domain-name {
     type string {
       pattern
         '((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*'
       + '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)'
       + '|\.';
       length "1..253";
     }
   }

   leaf hostname {
     type inet:domain-name;
   }

4.1.1. Использование SID

Как и в последующих примера приращение во внешнем отображении предполагает нулевое значение YANG SID (текущий узел схемы).

Диагностическая нотация CBOR

   {
     1752 : "myhost.example.com"     / hostname (SID 1752) /
   }

Представление CBOR

   A1                                         # map(1)
      19 06D8                                 # unsigned(1752)
      72                                      # text(18)
         6D79686F73742E6578616D706C652E636F6D # "myhost.example.com"

4.1.2. Использование имени

Диагностическая нотация CBOR

   {
     "ietf-system:hostname" : "myhost.example.com"
   }

Представление CBOR

   A1                                         # map(1)
      74                                      # text(20)
         696574662D73797374656D3A686F73746E616D65
      72                                      # text(18)
         6D79686F73742E6578616D706C652E636F6D

4.2. Контейнеры и другие узлы из дерева данных

Экземпляры контейнеров, структур данных YANG, содержимого уведомлений, ввода и вывода RPC и действий должны кодироваться с использованием элемента данных отображения CBOR (базовый тип 5). такое же кодирование применяется для элементов списка (параграф 4.4) и узлов anydata (параграф 4.5). Совместно их называют контейнероподобными экземплярами (container-like instances).

Отображение состоит из пар элементов ключ-значение. Каждому ключу с отображении CBOR назначается идентификатор узла схемы, а значению – значение узла представления в соответствии с типом данных экземпляра.

Эта спецификация поддерживает два типа ключей для отображений CBOR – SID (параграф 3.2) и имя (параграф 3.3).

В приведённых ниже применах, взятых из из [RFC6991] и [RFC7317], показано кодирование представления экземпляра контейнера system-state с использованием SID и имени.

   typedef date-and-time {
     type string {
       pattern '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?'
             + '(Z|[\+\-]\d{2}:\d{2})';
     }
   }

   container system-state {
     container clock {
       leaf current-datetime {
         type date-and-time;
       }

       leaf boot-datetime {
         type date-and-time;
       }
     }
   }

4.2.1. Использование SID

В контексте контейнеров и других узлов дерева данных ключи отображений CBOR во внутренних отображениях можно кодировать с помощью приращений (целое число) или абсоютных SID (с тегом 47). Расчёт приращений показан ниже.

  • Для container приращение равно SID текущего узла представления за вычетом SID родительского контейнера.

  • Для list приращения равно SID текущего узла представления за вычетом SID родительского списка.

  • Для RPC input и RPC output приращения равны SID текущего узла представления за вычетом SID RPC.

  • Для action input и action output приращения равны SID текущего узла представления за вычетом SID action.

  • Для содержимого уведомления приращение равно SID текущего узла представления минус SID notification.

Диагностическая нотация CBOR

   {
     1720 : {                              / system-state (SID 1720) /
       1 : {                               / clock  (SID 1721) /
         2 : "2015-10-02T14:47:24Z-05:00", / current-datetime(SID 1723)/
         1 : "2015-09-15T09:12:58Z-05:00"  / boot-datetime (SID 1722) /
       }
     }
   }

Представление CBOR

   A1                                      # map(1)
      19 06B8                              # unsigned(1720)
      A1                                   # map(1)
         01                                # unsigned(1)
         A2                                # map(2)
            02                             # unsigned(2)
            78 1A                          # text(26)
               323031352D31302D30325431343A34373A32345A2D30353A3030
            01                             # unsigned(1)
            78 1A                          # text(26)
               323031352D30392D31355430393A31323A35385A2D30353A3030

Рисунок 2. Кодирование System State Clock.


4.2.2. Использование имени

Ключи отображений CBOR на основе имён должны кодироваться с использованием тектовых строк CBOR (базовый тип 3). Должны применяться полные (namespace-qualified) имена, если пространства имён узла представления и его родителя различаются. В остальных случаях должны применяться простые имена. Имена и пространства имён определены в разделе 4 [RFC7951].

Ниже приведён пример кодирования экземпляра узла представления контейнера system с использованием имени.

Диагностическая нотация CBOR

   {
     "ietf-system:system-state" : {
       "clock" : {
         "current-datetime" : "2015-10-02T14:47:24Z-05:00",
         "boot-datetime" : "2015-09-15T09:12:58Z-05:00"
       }
     }
   }

Представление CBOR

   A1                                      # map(1)
      78 18                                # text(24)
         696574662D73797374656D3A73797374656D2D7374617465
      A1                                   # map(1)
         65                                # text(5)
            636C6F636B                     # "clock"
         A2                                # map(2)
            70                             # text(16)
               63757272656E742D6461746574696D65
            78 1A                          # text(26)
               323031352D31302D30325431343A34373A32345A2D30353A3030
            6D                             # text(13)
               626F6F742D6461746574696D65
            78 1A                          # text(26)
               323031352D30392D31355430393A31323A35385A2D30353A3030

4.3. leaf-list

Для кодирования leaf-list должен использоваться элемент данных массива CBOR (базовый тип 4). Каждая запись массива должна кодироваться с использованием одного из правил, заданных в разделе 6.

Приведённые ниже примеры из [RFC6991] и [RFC7317] показывают кодирование экземпляра представления листа-списка search с записями ietf.org и ieee.org.

   typedef domain-name {
     type string {
       pattern
         '((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*'
       + '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)'
       + '|\.';
       length "1..253";
     }
   }

   leaf-list search {
     type domain-name;
     ordered-by user;
   }

4.3.1. Использование SID

Диагностическая нотация CBOR

   {
     1746 : [ "ietf.org", "ieee.org" ]     / search (SID 1746) /
   }

Представление CBOR

   A1                        # map(1)
      19 06D2                # unsigned(1746)
      82                     # array(2)
         68                  # text(8)
            696574662E6F7267 # "ietf.org"
         68                  # text(8)
            696565652E6F7267 # "ieee.org"

4.3.2. Использование имени

Диагностическая нотация CBOR

   {
     "ietf-system:search" : [ "ietf.org", "ieee.org" ]
   }

Представление CBOR

   A1                                         # map(1)
      72                                      # text(18)
         696574662D73797374656D3A736561726368 # "ietf-system:search"
      82                                      # array(2)
         68                                   # text(8)
            696574662E6F7267                  # "ietf.org"
         68                                   # text(8)
            696565652E6F7267                  # "ieee.org"

4.4. Списки и записи списков

Список или часть списка должны кодироваться с использованием элемента данных массива CBOR (базовый тип 4). Каждая запись списка в массиве CBOR кодируется с использованием элемента данных отображения CBOR (базовый тип 5) по правилам кодирования контейнероподобных экземляров, приведённым в параграфе 4.2.

Важно отметить, что это правило кодирования применимо и к экземплярам узла представления list с 1 элементом.

Пример определения из [RFC7317] показывает кодирование списка server с использованием SID и имени.

   list server {
     key name;

     leaf name {
       type string;
     }
     choice transport {
       case udp {
         container udp {
           leaf address {
             type host;
             mandatory true;
           }
           leaf port {
             type port-number;
           }
         }
       }
     }
     leaf association-type {
       type enumeration {
         enum server;
         enum peer;
         enum pool;
       }
       default server;
     }
     leaf iburst {
       type boolean;
       default false;
     }
     leaf prefer {
       type boolean;
       default false;
     }
   }

4.4.1. Использование SID

Правила кодирования для каждой записи list приведены в параграфе 4.2.1.

Диагностическая нотация CBOR

   {
     1756 : [                      / server (SID 1756) /
       {
         3 : "NRC TIC server",     / name (SID 1759) /
         5 : {                     / udp (SID 1761) /
           1 : "tic.nrc.ca",       / address (SID 1762) /
           2 : 123                 / port (SID 1763) /
         },
         1 : 0,                    / association-type (SID 1757) /
         2 : false,                / iburst (SID 1758) /
         4 : true                  / prefer (SID 1760) /
       },
       {
         3 : "NRC TAC server",     / name (SID 1759) /
         5 : {                     / udp (SID 1761) /
           1 : "tac.nrc.ca"        / address (SID 1762) /
         }
       }
     ]
   }

Представление CBOR

   A1                                      # map(1)
      19 06DC                              # unsigned(1756)
      82                                   # array(2)
         A5                                # map(5)
            03                             # unsigned(3)
            6E                             # text(14)
               4E52432054494320736572766572 # "NRC TIC server"
            05                             # unsigned(5)
            A2                             # map(2)
               01                          # unsigned(1)
               6A                          # text(10)
                  7469632E6E72632E6361     # "tic.nrc.ca"
               02                          # unsigned(2)
               18 7B                       # unsigned(123)
            01                             # unsigned(1)
            00                             # unsigned(0)
            02                             # unsigned(2)
            F4                             # primitive(20)
            04                             # unsigned(4)
            F5                             # primitive(21)
         A2                                # map(2)
            03                             # unsigned(3)
            6E                             # text(14)
               4E52432054414320736572766572 # "NRC TAC server"
            05                             # unsigned(5)
            A1                             # map(1)
               01                          # unsigned(1)
               6A                          # text(10)
                  7461632E6E72632E6361     # "tac.nrc.ca"

4.4.2. Использование имени

Правила кодирования для каждой записи list приведены в параграфе 4.2.2.

Диагностическая нотация CBOR

   {
     "ietf-system:server" : [
       {
         "name" : "NRC TIC server",
         "udp" : {
           "address" : "tic.nrc.ca",
           "port" : 123
         },
         "association-type" : 0,
         "iburst" : false,
         "prefer" : true
       },
       {
         "name" : "NRC TAC server",
         "udp" : {
           "address" : "tac.nrc.ca"
         }
       }
     ]
   }

Представление CBOR

   A1                                      # map(1)
      72                                   # text(18)
         696574662D73797374656D3A736572766572
      82                                   # array(2)
         A5                                # map(5)
            64                             # text(4)
               6E616D65                    # "name"
            6E                             # text(14)
               4E52432054494320736572766572
            63                             # text(3)
               756470                      # "udp"
            A2                             # map(2)
               67                          # text(7)
                  61646472657373           # "address"
               6A                          # text(10)
                  7469632E6E72632E6361     # "tic.nrc.ca"
               64                          # text(4)
                  706F7274                 # "port"
               18 7B                       # unsigned(123)
            70                             # text(16)
               6173736F63696174696F6E2D74797065
            00                             # unsigned(0)
            66                             # text(6)
               696275727374                # "iburst"
            F4                             # primitive(20)
            66                             # text(6)
               707265666572                # "prefer"
            F5                             # primitive(21)
         A2                                # map(2)
            64                             # text(4)
               6E616D65                    # "name"
            6E                             # text(14)
               4E52432054414320736572766572
            63                             # text(3)
               756470                      # "udp"
            A1                             # map(1)
               67                          # text(7)
                  61646472657373           # "address"
               6A                          # text(10)
                  7461632E6E72632E6361     # "tac.nrc.ca"

4.5. anydata

Узлы anydata служат контейнерами для произвольных наборов узлов представления, которые иначе появлялись бы как обычные данные модели YANG. Экземпляр узла представления anydata кодируется с использованием правил, применяемых для контейнеров, т. е. с применением элементов данных отображения CBOR (базовый тип 5) по правилам кодирования контейнероподобных экземпляров, указанным в параграфе 4.2.

Ниже приведён пример, показывающий возможное использование узла anydata. Здесь узел anydata служит для определения узла представления, содержащего уведомление, этот узел может быть частью списка YANG для записи событий.

   module event-log {
     ...
     anydata last-event;                // SID 60123
   }

В этом примере предполагается участие приведённого ниже уведомления.

   module example-port {
     ...

     notification example-port-fault {  // SID 60200
       leaf port-name {                 // SID 60201
         type string;
       }
       leaf port-fault {                // SID 60202
         type string;
       }
     }
   }

4.5.1. Использование SID

Диагностическая нотация CBOR

   {
     60123 : {                   / last-event (SID 60123) /
       77 : {                    / example-port-fault (SID 60200) /
         1 : "0/4/21",           / port-name (SID 60201) /
         2 : "Open pin 2"        / port-fault (SID 60202) /
       }
     }
   }

Представление CBOR

   A1                               # map(1)
      19 EADB                       # unsigned(60123)
      A1                            # map(1)
         18 4D                      # unsigned(77)
         A2                         # map(2)
            01                      # unsigned(1)
            66                      # text(6)
               302F342F3231         # "0/4/21"
            02                      # unsigned(2)
            6A                      # text(10)
               4F70656E2070696E2032 # "Open pin 2"

В некоторых реализациях может быть проще использовать кодирование абсолютных SID (тег 47) для корневого элемента anydata.

Диагностическая нотация CBOR

   {
     60123 : {                   / last-event (SID 60123) /
       47(60200) : {             / event-port-fault (SID 60200) /
         1 : "0/4/21",           / port-name (SID 60201) /
         2 : "Open pin 2"        / port-fault (SID 60202) /
       }
     }
   }

4.5.2. Использование имени

Диагностическая нотация CBOR

   {
     "event-log:last-event" : {
       "example-port:example-port-fault" : {
         "port-name" : "0/4/21",
         "port-fault" : "Open pin 2"
       }
     }
   }

Представление CBOR

   A1                                      # map(1)
      74                                   # text(20)
         6576656E742D6C6F673A6C6173742D6576656E74
      A1                                   # map(1)
         78 1F                             # text(31)
            6578616D706C652D706F72743A
            6578616D706C652D706F72742D6661756C74
         A2                                # map(2)
            69                             # text(9)
               706F72742D6E616D65          # "port-name"
            66                             # text(6)
               302F342F3231                # "0/4/21"
            6A                             # text(10)
               706F72742D6661756C74        # "port-fault"
            6A                             # text(10)
               4F70656E2070696E2032        # "Open pin 2"

4.6. anyxml

Узлы представления anyxml служат для сериализации произвольного содержимого CBOR, т. е. значением может быть любой двоичный объект CBOR (xml в названии не вполне корректно, поскольку применяется лишь к YANG-XML [RFC7950]). Значение anyxml может содержать элементы данных CBOR, помеченные одним из тегов, указанных в параграфе 9.3. Эти теги нужно поддерживать.

В приведённых ниже примерах из [RFC7951] показан действительный экземпляр узла представления anyxml с кодированием CBOR, содержащий массив CBOR с простыми значениями CBOR true, null, true.

   module bar-module {
     ...
     anyxml bar;      // SID 60000
   }

4.6.1. Использование SID

Диагностическая нотация CBOR

   {
     60000 : [true, null, true]   / bar (SID 60000) /
   }

Представление CBOR

   A1         # map(1)
      19 EA60 # unsigned(60000)
      83      # array(3)
         F5   # primitive(21)
         F6   # primitive(22)
         F5   # primitive(21)

4.6.2. Использование имени

Диагностическая нотация CBOR

   {
     "bar-module:bar" : [true, null, true]   / bar (SID 60000) /
   }

Представление CBOR

   A1                                 # map(1)
      6E                              # text(14)
         6261722D6D6F64756C653A626172 # "bar-module:bar"
      83                              # array(3)
         F5                           # primitive(21)
         F6                           # primitive(22)
         F5                           # primitive(21)

5. Кодирование расширения yang-data

Расширение yang-data [RFC8040] служит для определения в YANG структур данных, не предназначенных для реализации как части хранилища. Расширение yang-data будет задавать контейнер, который должен кодироваться по правилам для узлов дерева данных, указанным в параграфе 4.2. Как и контейнеры YANG, расширение yang-data можно кодировать с использованием SID или имени.

Пример определения из Приложения A к [CORE-COMI]

   module ietf-coreconf {
     ...

     import ietf-restconf {
       prefix rc;
     }

     rc:yang-data yang-errors {
       container error {
         leaf error-tag {
           type identityref {
             base error-tag;
           }
         }
         leaf error-app-tag {
           type identityref {
             base error-app-tag;
           }
         }
         leaf error-data-node {
           type instance-identifier;
         }
         leaf error-message {
           type string;
         }
       }
     }
   }

5.1. Использование SID

Расширения yang-data, закодированные с использованием SID, передаются в отображении CBOR с одной парой элементов. Для ключа устанавливается значение SID, выделенное контейнеру расширения yang-data, а в значение помещается CBOR-кодирование этого контейнера, как задано в параграфе 4.2.

Приведённый ниже пример сериализации экземпляра yang-errors расширения yang-data, как определено в [CORE-COMI], с использованием SID в соответствии с параграфом 3.2.

Диагностическая нотация CBOR

   {
     1024 : {                      / error  (SID 1024) /
       4 : 1011,                   / error-tag (SID 1028) /
                                   / = invalid-value (SID 1011) /
       1 : 1018,                   / error-app-tag (SID 1025) /
                                   / = not-in-range (SID 1018) /
       2 : 1740,                   / error-data-node (SID 1026) /
                                   / = timezone-utc-offset (SID 1740) /
       3 : "Maximum exceeded"      / error-message (SID 1027) /
     }
   }

Представление CBOR

   A1                                      # map(1)
      19 0400                              # unsigned(1024)
      A4                                   # map(4)
         04                                # unsigned(4)
         19 03F3                           # unsigned(1011)
         01                                # unsigned(1)
         19 03FA                           # unsigned(1018)
         02                                # unsigned(2)
         19 06CC                           # unsigned(1740)
         03                                # unsigned(3)
         70                                # text(16)
            4D6178696D756D206578636565646564 # "Maximum exceeded"

5.2. Использование имени

Расширение yang-data закодированное с использованием имени передаётся в отображении CBOR с одной парой элементов. Для ключа устанавливается полное (namespace-qualified) имя контейнера расширения yang-data, а значением служит CBOR-кодирование этого контейнера, как указано в параграфе 4.2.

Ниже приведён пример сериализации экземпляра yang-errors расширения yang-data, определённого в [CORE-COMI], с использованием имени, как указано в параграфе 3.3.

Диагностическая нотация CBOR

   {
     "ietf-coreconf:error" : {
       "error-tag" : "invalid-value",
       "error-app-tag" : "not-in-range",
       "error-data-node" : "timezone-utc-offset",
       "error-message" : "Maximum exceeded"
     }
   }

Представление CBOR

   A1                                           # map(1)
      73                                        # text(19)
         696574662D636F7265636F6E663A6572726F72 # "ietf-coreconf:error"
      A4                                        # map(4)
         69                                     # text(9)
            6572726F722D746167                  # "error-tag"
         6D                                     # text(13)
            696E76616C69642D76616C7565          # "invalid-value"
         6D                                     # text(13)
            6572726F722D6170702D746167          # "error-app-tag"
         6C                                     # text(12)
            6E6F742D696E2D72616E6765            # "not-in-range"
         6F                                     # text(15)
            6572726F722D646174612D6E6F6465      # "error-data-node"
         73                                     # text(19)
            74696D657A6F6E652D7574632D6F6666736574
                                                # "timezone-utc-offset"
         6D                                     # text(13)
            6572726F722D6D657373616765          # "error-message"
         70                                     # text(16)
            4D6178696D756D206578636565646564    # "Maximum exceeded"

6. Представление типов данных YANG в CBOR

Кодирование CBOR для экземпляра узла представления leaf или leaf-list зависит от встроенного типа этого узла представления. Ниже определяется кодирование CBOR для каждого встроенного типа, поддерживаемого в YANG (см. параграф 4.2.4 в [RFC7950]). В каждом параграфе приведён пример значения, выделенного экземпляру узла представления обсуждаемого встроенного типа.

6.1. Целочисленные типы без знака

Листья типов uint8, uint16, uint32, uint64 должны кодироваться с использованием беззнакового целочисленного элемента данных CBOR (базовый тип 0).

Пример из [RFC8344] показывает кодирование экземпляра узла представления mtu со значением 1280 байтов.

   leaf mtu {
     type uint16 {
       range "68..max";
     }
   }

Диагностическая нотация CBOR: 1280

Представление CBOR: 19 0500

6.2. Целочисленные типы

Листья типов int8, int16, int32, int64 должны кодироваться с использованием беззнакового целочисленного элемента данных CBOR (базовый тип 0) или отрицательного целого числа CBOR (базовый тип 1), в зависимости от фактического значения.

Пример из [RFC7317] показывает кодирование экземпляра узла представления timezone-utc-offset со значением -300 минут.

Пример определения из [RFC7317]

   leaf timezone-utc-offset {
     type int16 {
       range "-1500 .. 1500";
     }
   }

Диагностическая нотация CBOR: -300

Представление CBOR: 39 012B

6.3. decimal64

Листья типа decimal64 должны кодироваться с использованием десятичной дроби, как указано в параграфе 3.4.4 [RFC8949].

Пример из [RFC7317] показывает кодирование экземпляра узла представления my-decimal со значением 2,57.

   leaf my-decimal {
     type decimal64 {
       fraction-digits 2;
       range "1 .. 3.14 | 10 | 20..max";
     }
   }

Диагностическая нотация: CBOR 4([-2, 257])

Представление CBOR: C4 82 21 19 0101

6.4. string

Листья типа string должны кодироваться с использованием текстовой строки CBOR (базовый тип 3).

Пример из [RFC8343] показывает кодирование экземпляра узла представления name со значением eth0.

   leaf name {
     type string;
   }

Диагностическая нотация CBOR: “eth0”

Представление CBOR: 64 65746830

6.5. boolean

Листья типа boolean должны кодироваться с использованием простого значения CBOR true (базовый тип 7, дополнительное значение 21) или false (базовый тип 7, дополнительное значение 20).

Пример из [RFC7317] показывает кодирование экземпляра узла представления enabled со значением true.

   leaf enabled {
     type boolean;
   }

Диагностическая нотация CBOR: true

Представление CBOR: F5

6.6. enumeration

Листья типа enumeration должны кодироваться с использованием беззнакового целочисленного элемента данных CBOR (базовый тип 0) или отрицательного целого числа CBOR (базовый тип 1), в зависимости от фактического значения, или, в качестве исключения, как строка текста с тегом (см. ниже). Перечисляемые значения выделяются явно с использованием оператора YANG value или автоматически на основе алгоритма, описанного в параграфе 9.6.4.2 [RFC7950].

Пример из [RFC7317] показывает кодирование экземпляра узла представления oper-status со значением testing.

   leaf oper-status {
     type enumeration {
       enum up { value 1; }
       enum down { value 2; }
       enum testing { value 3; }
       enum unknown { value 4; }
       enum dormant { value 5; }
       enum not-present { value 6; }
       enum lower-layer-down { value 7; }
     }
   }

Диагностическая нотация CBOR: 3

Представление CBOR: 03

Значения типа enumeration, заданные в типе union должны кодироваться с использованием строки текста CBOR (базовый тип 3) и должны содержать одно из имён, назначенных оператором enum в YANG (см. параграф 6.12). Кодирование должно использовать тег перечисления CBOR, как указано в параграфе 9.3.

Пример определения из [RFC7950]

   type union {
     type int32;
     type enumeration {
       enum unbounded;
     }
   }

Диагностическая нотация CBOR: 44(“unbounded”)

Представление CBOR: D8 2C 69 756E626F756E646564

6.7. bits

С учётом того, что биты назначаются явно с помощью оператора YANG position или автоматически на основе алгоритма, заданного в параграфе 9.7.4.2 [RFC7950], каждый элемент типа bits можно рассматривать как набор битовых позиций (или смещений от позиции 0), имеющих значение 1 (бит установлен) или 0 (бит сброшен).

Листья типа bits должны кодироваться с использованием массива CBOR (базовый тип 4) или строки байтов (базовый тип 2), а в исключительных случаях – строки текста с тегом (см. ниже). При использовании массива CBOR каждый элемент является (1) положительным целым числом (базовый тип 0, дополнительное значение 0 не разрешено), которое служит для расчёта смещения следующей за ним строки байтов, или (2) строкой байтов (базовый тип 2) с информацией об установленных и сброшенных битах. Начальное смещение имеет значение 0 и каждое целое число без знака меняет смещение следующей за ним строки байтов на целое число, умноженное на 8. Например, если смещение бита равно 0 и имеется целое число 5, первый байт следующей строки байтов будет представлять битовые позиции от 40 до 47, включительно. Если строка байтов имеет второй байт, он будет содержать сведения о битах 48 – 55 и т. д. Внутри каждого байта биты назначаются от младшего к старшему. После строки байтов смещение меняется на число байтов в строке, умноженное на 8. Байты без установленных битов (0) в конце строки байтов не создаются. Если это происходит в конце массива, такие байты просто опускаются. Если же это возникает в конце строки байтов, предшествующей целому числу, байты с нулями удаляются и это целое число увеличивается на количество удалённых байтов с нулями.

В примере представлено кодирование экземпляра узла представления alarm-state с установленными флагами critical (позиция 2), warning ( позиция 8) и indeterminate (позиция 128).

   typedef alarm-state {
     type bits {
       bit unknown;
       bit under-repair;
       bit critical;
       bit major;
       bit minor;
       bit warning {
         position 8;
       }
       bit indeterminate {
         position 128;
       }
     }
   }

   leaf alarm-state {
     type alarm-state;
   }

Диагностическая нотация CBOR: [h’0401′, 14, h’01’]

Представление CBOR: 83 42 0401 0E 41 01

Во многих случаях массив будет содержать лишь 1 элемент – строку из нескольких байтов. В таком случае требуется опустить элемент массива и включать только строку (массив) байтов. В качестве примера рассмотрим приведённое выше определение YANG с кодированием лишь флагов under-repair и critical. Результат показан ниже.

Диагностическая нотация CBOR: h’06’

Представление CBOR: 41 06

Элементы массива должны быть строками байтов без нулевых байтов в конце или положительными целыми числами, которые должны чередоваться со строками байтов, т. е. два целых числа или две строки байтов подряд являются ошибкой. Массив с одной строкой байтов должен кодироваться просто как строка байтов. Массив с одним положительным целым числом является ошибкой. Отметим, что получатель может обрабатывать нулевые байты в конце по обычным правилам без каких-либо проблем, поэтому реализация может просто воспринимать их.

Значения типа bits, определённые в типе union, должны кодироваться с использованием строки текста CBOR (базовый тип 3) и должны содержать последовательность разделённых пробелами имён bits, которые установлены (см. параграф 6.12). Кодирование должно использовать тег CBOR, как указано в параграфе 9.3.

В примере показано кодирование экземпляра узла представления alarm-state, заданного с использованием типа union, где установлены флаги under-repair и critical.

   leaf alarm-state-2 {
     type union {
       type alarm-state;
       type bits {
         bit extra-flag;
       }
     }
   }

Диагностическая нотация CBOR: 43(“under-repair critical”)

Представление CBOR: D8 2B 75 756E6465722D72657061697220637269746963616C

6.8. binary

Листья типа binary должны кодироваться с использованием строки байтов CBOR (базовый тип 2).

Пример показывает кодирование экземпляра узла представления aes128-key со значением 0x1f1ce6a3f42660d888d92a4d8030476e.

   leaf aes128-key {
     type binary {
       length 16;
     }
   }

Диагностическая нотация CBOR: h’1F1CE6A3F42660D888D92A4D8030476E’

Представление CBOR 50: 1F1CE6A3F42660D888D92A4D8030476E

6.9. leafref

Листья типа leafref должны кодироваться по правилам узла представления, указанного оператором YANG path.

Приведённый пример из [RFC8343] показывает кодирование экземпляра узла представления interface-state-ref со значением eth1.

   typedef interface-state-ref {
     type leafref {
       path "/interfaces-state/interface/name";
     }
   }

   container interfaces-state {
     list interface {
       key "name";
       leaf name {
         type string;
       }
       leaf-list higher-layer-if {
         type interface-state-ref;
       }
     }
   }

Диагностическая нотация CBOR: “eth1”

Представление CBOR: 64 65746831

6.10. identityref

Спецификация поддерживает два подхода к кодированию identityref с применением YANG SID (параграф 3.2) или имени (параграф 6.8 в [RFC7951]). Исключение, требующее применять тег, описано в параграфе 6.12.

6.10.1. SID как identityref

При реализации узла представления типа identityref с применением SID он должен кодироваться целым числом без знака CBOR (базовый тип 0). Отметим, что механизм приращений для SID в качестве identityref не применяется, поскольку они не используются как ключи отображения CBOR.

Пример из [RFC7317] показывает кодирование экземпляра узла представления type со значением iana-if-type:ethernetCsmacd (SID 1880).

   identity interface-type {
   }

   identity iana-interface-type {
     base interface-type;
   }

   identity ethernetCsmacd {
     base iana-interface-type;
   }

   leaf type {
     type identityref {
       base interface-type;
     }
   }

Диагностическая нотация CBOR: 1880

Представление CBOR: 19 0758

6.10.2. Имя как identityref

Можно кодировать identityref с использованием имени, как указано в параграфе 3.3. В этом случае для кодирования identityref должна использоваться строка текста CBOR (базовый тип 3). Если отождествление задано не в том модуле, где содержится узел данных identityref, должно указываться полное (namespace-qualified) имя, в остальных случаях разрешены обе формы имён (см. параграф 3.3).

В примере показано кодирование отождествления iana-if-type:ethernetCsmacd с применением полного имени (см. параграф 6.10.1).

Диагностическая нотация CBOR: “iana-if-type:ethernetCsmacd”

Представление CBOR: 78 1B 69616E612D69662D747970653A65746865726E657443736D616364

6.11. empty

Листья типа empty должны кодироваться с использованием значения CBOR null (базовый тип 7, дополнительное значение 22).

Пример из [RFC8344] показывает кодирование экземпляра узла представления is-router, когда он имеется.

   leaf is-router {
     type empty;
   }

Диагностическая нотация CBOR: null

Представление CBOR: F6

6.12. union

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

  • bits;

  • enumeration;

  • identityref;

  • instance-identifier.

Значения тегов CBOR указаны в параграфе 9.3.

Как отмечено в параграфах 6.6 и 6.7, типы enumeration и bits кодируются с помощью текстовых строк CBOR (базовый тип 3) при определении внутри типа union. Это повышает сложность, но необходимо из-за особенностей модели данных YANG для union – обходной путь обеспечивает совместимость с кодированием перекрывающихся объединений (union) в XML и JSON (см. параграф 9.12 в [RFC7950].)

Пример из [RFC6991] показывает кодирование экземпляра узла представления ip-address для значения 2001:db8:a0b:12f0::1.

   typedef ipv4-address {
     type string {
       pattern
         '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
       +  '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
       + '(%[\p{N}\p{L}]+)?';
     }
   }

   typedef ipv6-address {
     type string {
       pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
             + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
             + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
             + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
             + '(%[\p{N}\p{L}]+)?';
       pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
             + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
             + '(%.+)?';
     }
   }

   typedef ip-address {
     type union {
       type ipv4-address;
       type ipv6-address;
     }
   }

   leaf address {
     type ip-address;
   }

Диагностическая нотация CBOR: “2001:db8:a0b:12f0::1”

Представление CBOR: 74 323030313A6462383A6130623A313266303A3A31

6.13. instance-identifier

Эта спецификация поддерживает два подхода к кодированию instance-identifier на основе YANG SID (параграф 3.2) и имён (параграф 3.3). Исключение, требующее применять тег, описано в параграфе 6.12.

6.13.1. SID как instance-identifier

SID однозначно указывает узел схемы. В случае одного экземпляра узла схемы, т. е. при его определении в корне модуля или субмодуля YANG или определении узлов схемы в контейнере, SID достаточно для идентификации экземпляра (узла представления). Отметим, что механизм приращений для SID не применяется (см. параграф 6.10.1.)

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

В случае одного экземпляра кодирование instance-identifier должно использовать целое число без знака CBOR (базовый тип 0) со значением SID целевого узла схемы.

В списке YANG для кодирования instance-identifier должен применяться массив CBOR (базовый тип 4), как указано ниже:

  • первый элемент должен кодироваться как целое число без знака (базовый тип 0) со значением SID целевого узла схемы;

  • следующие элементы должны содержать значение ключа, требуемого для идентификации целевого узла схемы. Эти ключи должны быть упорядочены, как указано в операторе YANG key, начиная со списка верхнего уровня и продолжая подчинёнными списками.

Примеры в этом параграфе предполагают определение узла схемы типа instance-identifier. Пример определения из [RFC7950]

   container system {
     ...
     leaf reporting-entity {
       type instance-identifier;
     }

Первый пример

Пример определения из [RFC7317] показывает кодирование экземпляра узла представления reporting-entity со значением /system/contact (SID 1741).

   container system {

     leaf contact {
       type string;
     }

     leaf hostname {
       type inet:domain-name;
     }
   }

Диагностическая нотация CBOR: 1741

Представление CBOR: 19 06CD

Второй пример

Этот пример предназначен для демонстрации идентификации записи узла представления в списке YANG с использованием изменённой версии модуля YANG из [RFC7317] (добавление страны к листься и уполномоченным ключам). Пример иллюстрирует кодирование значения reporting-entity. Указывающего экземпляр списка /system/authentication/user/authorized-key/key-data (предполагается SID 1734) для имени пользователя bob и уполномоченного ключа с именем admin и страной france.

   list user {
     key name;

     leaf name {
       type string;
     }

     leaf password {
       type ianach:crypt-hash;
     }

     list authorized-key {
       key "name country";

       leaf country {
         type string;
       }

       leaf name {
         type string;
       }

       leaf algorithm {
         type string;
       }

       leaf key-data {
         type binary;
       }
     }
   }

Диагностическая нотация CBOR: [1734, “bob”, “admin”, “france”]

Представление CBOR

   84                 # array(4)
      19 06C6         # unsigned(1734)
      63              # text(3)
         626F62       # "bob"
      65              # text(5)
         61646D696E   # "admin"
      66              # text(6)
         6672616E6365 # "france"

Третий пример

Приведённый ниже пример показывает кодирование значения reporting-entity, указывающего экземпляр списка /system/authentication/user (SID 1730), соответствующий имени пользователя jack.

Диагностическая нотация CBOR: [1730, “jack”]

Представление CBOR

   82             # array(2)
      19 06C2     # unsigned(1730)
      64          # text(4)
         6A61636B # "jack"

6.13.2. Имена как instance-identifier

Значение instance-identifier кодируется как строка текста, аналогично лексическму представлению в XML (см. параграф 9.13.2 в [RFC7950]). Однако кодирование пространства имён в instance-identifier следует правилам параграфа 3.3:

  • самое левое (верхнего уровня) имя узла данных всегда имеет полную форму (namespace-qualified);

  • последующие имена узлов имеют полную форму, если узел определён не в родительском модуле, иначе применяется простая форма (это справедливо и для имён узлов в предикатах).

Например, /ietf-interfaces:interfaces/interface[name=’eth0′]/ietf-ip:ipv4/ip является действительным значением instance-identifier, поскольку узлы данных interfaces, interface, name определены в модуле ietf-interfaces, а ipv4 и ip – в ietf-ip.

Полученное в результате значение XML Path Language (XPath) должно кодироваться с использованием строки текста CBOR (базовый тип 3).

Ниже приведены примеры, описанные в параграфе 6.13.1.

Первый пример

Диагностическая нотация CBOR: “/ietf-system:system/contact”

Представление CBOR

   78 1B 2F696574662D73797374656D3A73797374656D2F636F6E74616374

Второй пример

Диагностическая нотация CBOR (the line break is inserted for exposition only)

   "/ietf-system:system/authentication/user[name='bob']/
   authorized-key[name='admin'][country='france']/key-data"

Представление CBOR

   78 6B
      2F696574662D73797374656D3A73797374656D2F61757468656E74696361
      74696F6E2F757365725B6E616D653D27626F62275D2F617574686F72697A
      65642D6B65795B6E616D653D2761646D696E275D5B636F756E7472793D27
      6672616E6365275D2F6B65792D64617461

Третий пример

Диагностическая нотация CBOR

   "/ietf-system:system/authentication/user[name='jack']"

Представление CBOR

   78 34                                   # text(52)
      2F696574662D73797374656D3A73797374656D2F61757468656E74696361
      74696F6E2F757365725B6E616D653D276A61636B275D

7. Content-Type

Эта спецификация определяет тип носителя application/yang-data+cbor, который можно использовать без параметров или с параметром id, содержащим имя (name) или SID (sid). Этот тип носителя представляет документ YANG-CBOR, содержащий дерево представления. При наличии параметра id в зависимости от его значения каждый узел представления указывается связанным с ним полным именем (namespace-qualified), как указано в параграфе 3.3 (id=name) или YANG SID (представленным, например, ключом отображения CBOR как приращение SID или с помощью тега 47), как указано в параграфе 3.2 (id=sid). При отсутствии параметра id могут применяться обе формы.

Форматом представления application/yang-data+cbor является отображение CBOR, сопоставляющее имена и/или SID (как указано выше) со значениями экземпляров (по правилам раздела 4).

В настоящее время не пердполагается использование для параметра id значений, отличающихся от имени и SID, или отсуствие параметра. Если такое расширение произойдёт, предполагается, что новые значения будут иметь форму [a-z][a-z0-9]*(-[a-z0-9]+)*.

Таким образом, документ задаёт 3 content-type, предназначенных для разных классов приложений.

  • application/yang-data+cbor, id=sid – для приложений, которым требуется экономить пространство кодирования и обработку строк текста (например, приложения на узлах с ограничениями [RFC7228] или с особыми требованиями к производительности).

  • application/yang-data+cbor, id=name – для приложений, которые не хотят поддерживать SID и располагают достаточными ресурсами для работы со строками текста (например, приложения, желающие напрямую заменить application/yang.data+json более эффективным представлением без внесения других изменений).

  • application/yang-data+cbor – для комплексных приложений, которые могут получить преимущество от повышенной эффективности идентификаторов SID, сохраняя интеграцию с базами модулей YANG, пока для них не заданы отображения SID.

Все три content-type основаны на одних механизмах представления, части которых в первом и втором случае просто не используются.

Использование одного из трёх content-type в транспортном протоколе выходит за рамки спецификации. В последнем абзаце параграфа 5.2 [RFC8040] рассматривается индикация и запрос использования конкретных content-type в RESTCONF. Похожие механизмы доступны в протоколе ограниченных приложений (Constrained Application Protocol или CoAP) [RFC7252] на основе опций Content-Format и Accept. В [CORE-COMI] показано, как можно использовать Content-Format для индикации в случае id=sid.

8. Вопросы безопасности

Применимы соображения безопасности, отмеченные в [RFC8949] и [RFC7950].

Этот документ определяет дополнительное кодирование данных, смоделированных на языке YANG. Кодирование само по себе не создаёт новых проблем безопасности в дополнение к отмеченным для конкретного проткола и контекста применения.

Для снижения рисков приложениям на приёмной стороне следует отвергать все сообщения, не соответствующие правилам этого документа, возвращая отправителю подходящее сообщение об ошибке. Например, при использовании параметра id для типа носителя важно корректно отклонять идентификаторы иного типа, чтобы избежать ситуаций, когда другие реализации по-иному интерпретируют такое содержимое.

При использовании SID интерпретация кодированных данных зависит не только от наличия корректных модулей YANG, но и от правильного отображения SID. Поэтому поддержка и развитие сведений об отображении требует такой же осторожности, как и управление модулями YANG. Процедуры [CORE-SID] учитывают это обстоятельство.

9. Взаимодействие с IANA

9.1. Реестр Media Types

Агентство IANA добавило указанный в таблице 2 тип носителя в реестр Media Types [IANA.media-types].

Таблица 2. Реестр Media Types.

 

Имя

Шаблон

Документ

yang-data+cbor

application/yang-data+cbor

RFC 9254

 

Type name: application
Subtype name: yang-data+cbor
Required parameters: N/A
Optional parameters: id (раздел 7 в RFC 9254)
Encoding considerations: binary (CBOR)
Security considerations: раздел 8 в RFC 9254
Interoperability considerations: N/A
Published specification: RFC 9254
Applications that use this media type: Приложения, которым нужно компактное и эффективное представление данных моделей YANG
Fragment identifier considerations: Синтаксис и семантика идентификатров фрагментов для application/yang-data+cbor совпадают с заданными для application/cbor (на момент публикации этого документа синтаксис идентификации фрагментов для application/cbor не был определен)
Additional information:
Magic number(s): N/A
File extension(s): N/A
Macintosh file type code(s): N/A
Person & email address to contact for further information: почтовая конференция CORE WG (core@ietf.org) или IETF Applications and Real-Time Area (art@ietf.org)
Intended usage: COMMON
Restrictions on usage: N/A
Author: CoRE WG
Change controller: IETF

9.2. Реестр CoAP Content-Formats

Агентство IANA добавило указанные в таблице 3 значения Content-Formats в субреестр CoAP Content-Formats реестра Constrained RESTful Environments (CoRE) Parameters [IANA.core-parameters]. Применяется процедура Expert Review для диапазона 0 – 255 и IETF Review – для 256 – 9999.

Таблица 3. Реестр CoAP Content-Format.

 

Тип носителя

Кодирование

Идентификатор

Документ

application/yang-data+cbor

340

RFC 9254

application/yang-data+cbor; id=name

341

RFC 9254

application/yang-data+cbor; id=sid

140

RFC 9254

 

9.3. Реестр CBOR Tags

Агентство IANA выделило номера тегов CBOR в реестре CBOR Tags [IANA.cbor-tags] заданнов в параграфе 9.2 [RFC8949].

Таблица 4. Реестр CBOR Tags

Тег

Элемент данных

Семантика

Документ

43

Строка текста

Тип YANG bits, параграф 6.7.

RFC 9254

44

Строка текста

Тип YANG enumeration, параграф 6.6.

RFC 9254

45

Целое число без знака или строка текста

Тип YANG identityref, параграф 6.10.

RFC 9254

46

Целое число без знака, строка текста или массив

Тип YANG instance-identifier, параграф 6.13.

RFC 9254

47

Целое число без знака

Тип YANG Schema Item iDentifier (SID), параграф 3.2.

RFC 9254

10. Литература

10.1. Нормативные документы

[IANA.cbor-tags] IANA, “Concise Binary Object Representation (CBOR) Tags”, <https://www.iana.org/assignments/cbor-tags>.

[IANA.core-parameters] IANA, “Constrained RESTful Environments (CoRE) Parameters”, <https://www.iana.org/assignments/core-parameters/>.

[IANA.media-types] IANA, “Media Types”, <https://www.iana.org/assignments/media-types/>.

[RFC2119] Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels”, BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, <https://www.rfc-editor.org/info/rfc2119>.

[RFC5234] Crocker, D., Ed. and P. Overell, “Augmented BNF for Syntax Specifications: ABNF”, STD 68, RFC 5234, DOI 10.17487/RFC5234, January 2008, <https://www.rfc-editor.org/info/rfc5234>.

[RFC7950] Bjorklund, M., Ed., “The YANG 1.1 Data Modeling Language”, RFC 7950, DOI 10.17487/RFC7950, August 2016, <https://www.rfc-editor.org/info/rfc7950>.

[RFC7951] Lhotka, L., “JSON Encoding of Data Modeled with YANG”, RFC 7951, DOI 10.17487/RFC7951, August 2016, <https://www.rfc-editor.org/info/rfc7951>.

[RFC8040] Bierman, A., Bjorklund, M., and K. Watsen, “RESTCONF Protocol”, RFC 8040, DOI 10.17487/RFC8040, January 2017, <https://www.rfc-editor.org/info/rfc8040>.

[RFC8174] Leiba, B., “Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words”, BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, <https://www.rfc-editor.org/info/rfc8174>.

[RFC8259] Bray, T., Ed., “The JavaScript Object Notation (JSON) Data Interchange Format”, STD 90, RFC 8259, DOI 10.17487/RFC8259, December 2017, <https://www.rfc-editor.org/info/rfc8259>.

[RFC8610] Birkholz, H., Vigano, C., and C. Bormann, “Concise Data Definition Language (CDDL): A Notational Convention to Express Concise Binary Object Representation (CBOR) and JSON Data Structures”, RFC 8610, DOI 10.17487/RFC8610, June 2019, <https://www.rfc-editor.org/info/rfc8610>.

[RFC8791] Bierman, A., Björklund, M., and K. Watsen, “YANG Data Structure Extensions”, RFC 8791, DOI 10.17487/RFC8791, June 2020, <https://www.rfc-editor.org/info/rfc8791>.

[RFC8949] Bormann, C. and P. Hoffman, “Concise Binary Object Representation (CBOR)”, STD 94, RFC 8949, DOI 10.17487/RFC8949, December 2020, <https://www.rfc-editor.org/info/rfc8949>.

10.2. Дополнительная литература

[CORE-COMI] Veillette, M., Ed., van der Stok, P., Ed., Pelov, A., Bierman, A., and I. Petrov, Ed., “CoAP Management Interface (CORECONF)”, Work in Progress, Internet-Draft, draft-ietf-core-comi-11, 17 January 2021, <https://datatracker.ietf.org/doc/html/draft-ietf-core-comi-11>.

[CORE-SID] Veillette, M., Ed., Pelov, A., Ed., Petrov, I., Ed., Bormann, C., and M. Richardson, “YANG Schema Item iDentifier (YANG SID)”, Work in Progress, Internet-Draft, draft-ietf-core-sid-18, 18 November 2021, <https://datatracker.ietf.org/doc/html/draft-ietf-core-sid-18>.

[RFC6241] Enns, R., Ed., Bjorklund, M., Ed., Schoenwaelder, J., Ed., and A. Bierman, Ed., “Network Configuration Protocol (NETCONF)”, RFC 6241, DOI 10.17487/RFC6241, June 2011, <https://www.rfc-editor.org/info/rfc6241>.

[RFC6991] Schoenwaelder, J., Ed., “Common YANG Data Types”, RFC 6991, DOI 10.17487/RFC6991, July 2013, <https://www.rfc-editor.org/info/rfc6991>.

[RFC7228] Bormann, C., Ersue, M., and A. Keranen, “Terminology for Constrained-Node Networks”, RFC 7228, DOI 10.17487/RFC7228, May 2014, <https://www.rfc-editor.org/info/rfc7228>.

[RFC7252] Shelby, Z., Hartke, K., and C. Bormann, “The Constrained Application Protocol (CoAP)”, RFC 7252, DOI 10.17487/RFC7252, June 2014, <https://www.rfc-editor.org/info/rfc7252>.

[RFC7317] Bierman, A. and M. Bjorklund, “A YANG Data Model for System Management”, RFC 7317, DOI 10.17487/RFC7317, August 2014, <https://www.rfc-editor.org/info/rfc7317>.

[RFC8343] Bjorklund, M., “A YANG Data Model for Interface Management”, RFC 8343, DOI 10.17487/RFC8343, March 2018, <https://www.rfc-editor.org/info/rfc8343>.

[RFC8344] Bjorklund, M., “A YANG Data Model for IP Management”, RFC 8344, DOI 10.17487/RFC8344, March 2018, <https://www.rfc-editor.org/info/rfc8344>.

Благодарности

Этот документ в значительной мере вдохновлен обширной работой Andy Bierman и Peter van der Stok над [CORE-COMI]. Докумен [RFC7951] также внёс важный вклад в эту работу. Спасибо авторам и участникам создания этих документов.

Авторы хотели бы также поблагодарить Ladislav Lhotka и Jürgen Schönwälder, а также «куратора» документа Marco Tiloca за обзор, отзывы и комментации. Обширные комментарии в процессе рецензирования IESG помогли улучшить документ и авторы хотели бы особо отметить отзывы и рекомендации от руководителя направления (AD) Francesca Palombini, а также существенные улучшения, предложенные членами IESG Benjamin Kaduk и Rob Wilton.

Адреса авторов

Michel Veillette (editor)
Trilliant Networks Inc.
610 Rue du Luxembourg
Granby Quebec J2J 2V2
Canada
Email: michel.veillette@trilliantinc.com
 
Ivaylo Petrov (editor)
Google Switzerland GmbH
Brandschenkestrasse 110
CH-8002 Zurich
Switzerland
Email: ivaylopetrov@google.com
 
Alexander Pelov
Acklio
1137A avenue des Champs Blancs
35510 Cesson-Sevigne Cedex
France
Email: a@ackl.io
 
Carsten Bormann
Universität Bremen TZI
Postfach 330440
D-28359 Bremen
Germany
Phone: +49-421-218-63921
Email: cabo@tzi.org
 
Michael Richardson
Sandelman Software Works
Canada
Email: mcr+ietf@sandelman.ca

Перевод на русский язык

Николай Малых

nmalykh@protokols.ru

1Internet Engineering Task Force – комиссия по решению инженерных задач Internet.

2Internet Engineering Steering Group – комиссия по инженерным разработкам Internet.

Рубрика: RFC | Оставить комментарий

RFC 9260 Stream Control Transmission Protocol

image_print
Internet Engineering Task Force (IETF)                        R. Stewart
Request for Comments: 9260                                 Netflix, Inc.
Obsoletes: 4460, 4960, 6096, 7053, 8540                         M. Tüxen
Category: Standards Track                Münster Univ. of Appl. Sciences
ISSN: 2070-1721                                               K. Nielsen
                                                            Kamstrup A/S
                                                               June 2022

Протокол SCTP

Stream Control Transmission Protocol

PDF

Аннотация

Этот документ описывает протокол управления потоковой передачей (Stream Control Transmission Protocol или SCTP) и отменяет RFC 4960. Он включает спецификацию реестра флагов блоков (chunk) из RFC 6096 и спецификацию бита I в блоках DATA из RFC 7053, поэтому отменяет также RFC 6096 и RFC 7053. Кроме того, документ отменяет RFC 4460 и RFC 8540, где указаны ошибки для SCTP.

Протокол SCTP изначально был предназначен для передачи сигнальных сообщений PSTN1 через сети IP, но может использоваться и для других приложений, например, WebRTC.

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

  • передача пользовательских данных с корректировкой ошибок, подтверждением доставки и отсутствием дубликатов;
  • фрагментирование данных в соответствии с определенным для пути значением MTU2;
  • упорядоченная доставка пользовательских сообщений внутри множества потоков с возможностью управления порядком доставки отдельных пользовательских сообщений;
  • возможность группировки пользовательских сообщений в один пакет SCTP;
  • устойчивость к отказам на сетевом уровне за счёт поддержки многодомных хостов на обеих сторонах соединения.

Протокол SCTP включает механизмы предотвращения gthtuheprb и устойчивости к атакам с использованием лавины пакетов (flooding) или маскированием адресов (masquerade).

Статус документа

Документ относится к категории Internet Standards Track.

Документ является результатом работы IETF3 и представляет согласованный взгляд сообщества IETF. Документ прошёл открытое обсуждение и был одобрен для публикации IESG4. Дополнительную информацию о стандартах Internet можно найти в разделе 2 в RFC 7841.

Информацию о текущем статусе документа, ошибках и способах обратной связи можно найти по ссылке https://www.rfc-editor.org/info/rfc9260.

Авторские права

Авторские права (Copyright (c) 2022) принадлежат IETF Trust и лицам, указанным в качестве авторов документа. Все права защищены.

К документу применимы права и ограничения, перечисленные в BCP 78 и IETF Trust Legal Provisions и относящиеся к документам IETF (http://trustee.ietf.org/license-info), на момент публикации данного документа. Прочтите упомянутые документы внимательно, поскольку в них описаны права и ограничения, относящиеся к данному документу. Фрагменты программного кода, включённые в этот документ, распространяются в соответствии с упрощённой лицензией BSD, как указано в параграфе 4.e документа Trust Legal Provisions, без каких-либо гарантий (как указано в Simplified BSD License).

Документ может содержать материалы из IETF Document или IETF Contribution, опубликованных или публично доступных до 10 ноября 2008 года. Лица, контролирующие авторские права на некоторые из таких документов, могли не предоставить IETF Trust права разрешать внесение изменений в такие документы за рамками процессов IETF Standards. Без получения соответствующего разрешения от лиц, контролирующих авторские права этот документ не может быть изменён вне рамок процесса IETF Standards, не могут также создаваться производные документы за рамками процесса IETF Standards за исключением форматирования документа для публикации или перевода с английского языка на другие языки.

Оглавление

Исключено в версии HTML.

1. Введение

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

Этот документ заменяет собой [RFC4960]. Кроме того, он включает спецификацию реестра флагов блоков (chunk) из RFC 6096 и спецификацию бита I в блоках DATA из RFC 7053, поэтому отменяет также [RFC 6096] и [RFC 7053].

1.1. Мотивация

Протокол TCP [RFC0793] обеспечивает, прежде всего, гарантированную доставку данных в сетях IP. Однако многие современные приложения сталкиваются с ограниченными возможностями TCP и вынуждены реализовать свои средства обеспечения гарантированной доставки на основе транспорта UDP [RFC0768]. Ниже перечислены основные ограничения TCP, которые пользователи стремятся обойти.

  • Протокол TCP обеспечивает гарантию доставки данных с сохранением их порядка. Некоторым приложениям требуется лишь гарантированная доставка, независимо от порядка, а другим приложениям может быть достаточно частичного сохранения порядка доставки. Оба типа приложений не устраивают дополнительные задержки TCP, возникающие при нарушении порядка доставки пакетов в сети.
  • Потоковая природа протокола TCP зачастую не подходит для приложений, которым приходится вводить свои средства маркировки записей для делинеаризации передаваемых сообщений. Кроме того, приложениям приходиться явно использовать средства выталкивания данных (push) для того, чтобы сообщение было передано полностью за разумное время.
  • Ограниченные возможности сокетов TCP усложняют для приложений задачу обеспечения высокого уровня доступности при обмене данными за счёт использования многодомных5 хостов.
  • Протокол TCP достаточно слабо защищён от атак на службы6, в частности, от SYN-атак.

Передача сигнальных сообщений PSTN через сети IP является примером приложения, которое сталкивается со всеми ограничениями протокола TCP. Это послужило основным мотивом разработки протокола SCTP, но можно найти и другие приложения, для которых транспорт SCTP будет предпочтительным. Одним из примеров является использование каналов данных в инфраструктуре WebRTC.

1.2. Архитектура SCTP

Протокол SCTP размещается в многоуровневой модели между уровнем пользовательских приложений SCTP и сетевым сервисом без организации явных соединений (например, IP). В остальной части этого документа предполагается, что SCTP работает «поверх» протокола IP. Основным типом сервиса, обеспечиваемого протоколом SCTP, является гарантированная передача сообщений между пользователями SCTP. Этот сервис обеспечивается в контексте ассоциаций между парами конечных точек SCTP. В параграфе 10 данного документа приводится схематическое рассмотрение интерфейса API, который должен существовать на границе между протоколом SCTP и пользовательскими приложениями SCTP.

Протокол SCTP работает на основе явных соединений7, но ассоциация SCTP представляет собой более широкое понятие, нежели соединение TCP. Протокол SCTP обеспечивает для каждой конечной точки SCTP (см. параграф 1.4) способ обеспечения другой конечной точки (в процессе создания ассоциации) списком транспортных адресов (т. е. множеством адресов IP в комбинации с номером порта SCTP), которые конечная точка может использовать для связи и откуда она будет получать пакеты SCTP. Ассоциация может передавать данные с использованием всех возможных пар адресов отправителя и получателя, которые могут быть созданы на основе списков адресов конечных точек.

 _____________                                      _____________
| Приложения  |                                    | Приложения  |
|    SCTP     |                                    |    SCTP     |
|-------------|                                    |-------------|
|Транспортный |                                    |Транспортный |
| сервис SCTP |                                    | сервис SCTP |
|-------------|                                    |-------------|
|   Сетевой   |Один или       ----      Один или   |   Сетевой   |
|  сервис IP  |несколько       \/       несколько  |  сервис IP  |
|             |адресов IP      /\       адресов IP |             |
|_____________|               ----                 |_____________|

  SCTP-узел A |<-------- Сетевой транспорт ------->| SCTP-узел B

Рисунок 1. SCTP-ассоциация.

В дополнение к инкапсуляции пакетов SCTP в IPv4 и IPv6 возможна инкапсуляция в UDP, как указано в [RFC6951], или в DTLS, как указано в [RFC8261].

1.3. Основные термины

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

Active destination transport address – активный транспортный адрес получателя

Адрес транспортного уровня конечной точки-партнера, который отправитель рассматривает как доступный для приёма пользовательских сообщений.

Association Maximum DATA Chunk Size (AMDCS) – максимальный размер блока DATA для ассоциации

Меньшее из значение PMDCS (Path Maximum DATA Chunk Size) среди всех адресов получателя.

Bundling of Chunks – группировка блоков

Дополнительная операция мультиплексирования, позволяющая передать в одном пакете несколько блоков SCTP.

Bundling of User messages – группировка пользовательских сообщений

Дополнительная операция мультиплексирования, позволяющая передать в одном пакете несколько сообщений SCTP. Каждое пользовательское сообщение помещается в отдельный блок DATA.

Chunk – блок

Единица информации в пакете SCTP, содержащая заголовок блока (chunk header) и данные.

Congestion window (cwnd) – окно насыщения (перегрузки)

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

Cumulative TSN Ack Point – указатель на кумулятивный номер Ack

Значение TSN для последнего блока DATA, подтверждённого с использованием поля Cumulative TSN Ack в SACK.

Flightsize – размер данных «в пути»

Число остающихся данных для конкретного транспортного адреса получателя в данный момент.

Idle destination address – неиспользуемый адрес получателя

Адрес, который не используется для передачи пользовательских сообщений в течение некоторого периода (обычно ≥ HB.interval).

Inactive destination transport address – неактивный транспортный адрес получателя

Адрес, который считается неактивным в результате обнаружения ошибки, и не доступен для доставки пользовательских сообщений.

Message (user message) – (пользовательское) сообщение

Данные, полученные протоколом SCTP от протокола вышележащего уровня (Upper Layer Protocol или ULP).

Network Byte Order – сетевой порядок байтов

Порядок передачи байтов, при котором старший байт следует первым. Синоним Big Endian.

Ordered Message – упорядоченные сообщения

Пользовательские сообщения, доставленные в том же порядке, в котором они были помещены в поток.

Outstanding Data (Data Outstanding или Data In Flight) – остающиеся данные (данные «в пути»)

Общий размер блоков DATA связанных с остающимися TSN. Повторно передаваемый блок DATA учитывается в остающихся данных один раз. Блок DATA, сочтённый потерянным, но ещё не переданный повторно не относится к остающимся данным.

Outstanding TSN (в конечной точке SCTP)

Номер TSN (и связанный с ним блок DATA), который был передан конечной точкой, но его получение ещё не подтверждено.

“Out of the Blue” (OOTB) Packet

Пакет с корректным форматом, для которого получатель не может определить ассоциацию (см. параграф 8.4).

Path – путь

Маршрут, используемый пакетами SCTP, переданными одной конечной точкой SCTP по определённому транспортному адресу другой конечной точки SCTP. Передача пакетов по различным транспортным адресам удалённой точки не обязательно ведёт к изменению пути. В этой спецификации путь указывается транспортным адресом получателя, поскольку маршрутизация считается стабильной. Это включает, в частности, выбор адреса отправителя при отправке пакета получателю.

Path Maximum DATA Chunk Size (PMDCS) – максимальный размер блока DATA для пути

Максимальный размер блока DATA (включая заголовок блока), который помещается в пакет SCTP, не превышающий по размеру PMTU для конкретного адреса получателя.

Path Maximum Transmission Unit (PMTU)

Максимальный размер пакета SCTP (включая общий заголовок SCTP и все блоки вместе с их заполнением), который можно передать по конкретному адресу получателя без использования фрагментации на уровне IP.

Primary Path – основной путь

Комбинация адресов отправителя и получателя которая будет помещаться в исходящие пакеты SCTP по умолчанию. Адрес отправителя включён в определение потому, что реализации протокола могут указывать оба адреса (получателя и отправителя) для обеспечения контроля пути возврата блоков с откликами и выбора интерфейса для передачи пакетов многодомными хостами.

Receiver Window (rwnd) – окно получателя

Переменная SCTP, которую отправитель использует для хранения последнего рассчитанного значения размера окна приёма своего партнёра по ассоциации. Размер окна приёма задаётся количеством байтов. Значение размера позволяет отправителю определить величину свободного пространства в приёмном буфере получателя.

SCTP association – ассоциация SCTP

Протокольные отношения между конечными точками SCTP, включающие пару узлов SCTP и информацию о состоянии протокола (теги Verification, активные значения TSN и т. п.). Для уникальной идентификации ассоциаций SCTP могут использоваться пары транспортных адресов конечных точек ассоциации. Между любой парой конечных точек SCTP недопустимо одновременное существование нескольких ассоциаций.

SCTP endpoint – конечная точка SCTP

Логический приёмник/передатчик пакетов SCTP. Для многодомных хостов конечная точка SCTP представляется своему партнёру как комбинация набора допустимых транспортных адресов, по которым можно передавать пакеты SCTP и набора допустимых адресов транспортного уровня, с которых могут приниматься пакеты SCTP. Все транспортные адреса, используемые конечной точкой SCTP, должны быть связаны с одним номером порта, но могут иметь различные адреса IP. Транспортные адреса, используемые конечной точкой SCTP, недопустимо устанавливать для другой конечной точки SCTP (т. е. транспортный адрес каждой конечной точки SCTP уникален).

SCTP packet (packet) – пакет SCTP

Элемент данных, передаваемый через интерфейс между SCTP и пакетной сетью без организации соединений (например, IP). Пакет SCTP включает общий заголовок SCTP, блок пользовательских данных (DATA chunk) и может включать блок управления SCTP.

SCTP user application (SCTP user) – пользовательское приложение SCTP (пользователь SCTP)

Логический объект вышележащего уровня, который использует сервис SCTP. Используется также термин Upper-layer Protocol (ULP) – протокол вышележащего уровня.

Slow-Start Threshold (ssthresh) – порог замедленного старта

Переменная SCTP, определяющая пороговое значение, по которому конечная точка будет определять необходимость использования для конкретного транспортного адреса процедуры slow start или congestion avoidance. Значение ssthresh указывается в байтах.

State Cookie – куки состояния

Контейнер со всей информацией, требуемой для создания ассоциации.

Stream – поток

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

Stream Sequence Number – порядковый номер в потоке

16-битовый порядковый номер, используемый SCTP для упорядоченной доставки пользовательских сообщений в данном потоке. Каждому пользовательскому сообщению в потоке присваивается один порядковый номер.

Tie-Tags

Два 32-битовых случайных значений, которые вместе образуют 64-битовое одноразовое значение nonce. Эти теги используются в State Cookie и TCB для связывания недавно перезапущенной ассоциации с её предшественником на конечной станции, которая не была перезагружена, но, тем не менее, не может найти тегов Verification существующей ассоциации.

Transmission Control Block (TCB) – блок управления передачей

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

Transmission Sequence Number (TSN)- порядковый номер при передаче

32-битовый порядковый номер, используемый протоколом SCTP для нумерации передаваемых блоков. Значение TSN связывается с каждым блоком, который содержит пользовательские данные, чтобы дать возможность конечной точке SCTP на приёмной стороне подтвердить приём блока и обнаружить дубликаты.

Transport address – транспортный адрес

Адрес транспортного уровня обычно определяется комбинацией адреса сетевого уровня, транспортным протоколом и номером порта на транспортном уровне. При использовании SCTP в сетях IP транспортный адрес представляет собой комбинацию адреса IP и номера порта SCTP (транспортным протоколом является SCTP).

Unordered Message – неупорядоченное сообщение

Неупорядоченные сообщения могут передаваться с изменением их местоположения в потоке относительно других сообщений. Неупорядоченные сообщения могут размещаться в потоке перед упорядоченными или после них.

User message – пользовательское сообщение

Элемент данных, передаваемый через интерфейс между пользовательским приложением и уровнем SCTP.

Verification Tag – тег верификации

32-битовое беззнаковое целое значение, которое обычно выбирается с использованием генератора случайных чисел. Verification Tag позволяет получателю проверить принадлежность полученного пакета SCTP к ассоциации и избавиться от старых пакетов из прежних ассоциаций.

1.4. Сокращения

MAC – Message Authentication Code [RFC2104] (код аутентификации сообщения).

RTO – Retransmission Timeout (тайм-аут повтора передачи).

RTT – Round-Trip Time (время кругового обхода).

RTTVAR – Round-Trip Time Variation (вариации времени кругового обхода).

SCTP – Stream Control Transmission Protocol (протокол управления потоковой передачей).

SRTT – Smoothed RTT (сглаженное значение RTT).

TCB – Transmission Control Block (блок управления передачей).

TLV – Type-Length-Value coding format (формат представления тип-размер-значение).

TSN – Transmission Sequence Number (порядковый номер при передаче).

ULP – Upper-Layer Protocol (протокол вышележащего уровня).

1.5. Функциональность SCTP

Транспортный сервис SCTP можно разделить на несколько функциональных групп, показанных на рисунке 2.

           Пользовательские приложения SCTP
-----------------------------------------------------
 _____________                  ____________________
|             |                |   Упорядоченная    |
|             |                | доставка в потоке  |
|  Создание   |                |____________________|
|     и       |         ____________________________
|   разрыв    |        | Фрагментация польз. данных |
| ассоциаций  |        |____________________________|
|             |         ____________________________
|             |        |      Подтверждения         |
|             |        |    и предотвращения        |
|             |        |        перегрузки          |
|             |        |____________________________|
|             |         ____________________________
|             |        |     Связывание блоков      |
|             |        |____________________________|
|             |     ________________________________
|             |    |      Проверка пакетов          |
|             |    |________________________________|
|             |     ________________________________
|             |    |     Управление путями          |
|_____________|    |________________________________|

Рисунок 2. Функциональное представление сервиса SCTP.

1.5.1. Создание и разрыв ассоциаций

Ассоциации создаются по запросам пользователей SCTP (см. описание примитива ASSOCIATE на стр. 49 или SEND на стр. 50).

В процессе создания ассоциаций используется механизм cookie, подобный предложенному Кэрном (Karn) и Симпсоном (Simpson) в [RFC2522], для обеспечения защиты от атак на синхронизацию. Этот механизм использует четырехэтапное согласование (four-way handshake), в котором два последних этапа могут использоваться для передачи пользовательских данных в целях ускорения процедуры соединения. Стартовые последовательности описаны в разделе 5. Создание ассоциации.

Протокол SCTP обеспечивает аккуратное завершение работы активных ассоциаций (shutdown) по запросу пользователя SCTP (см. описание примитива SHUTDOWN на стр. 50). Протокол SCTP позволяет также разрывать ассоциации (abort) по запросу пользователя (примитив ABORT) или в результате обнаружения ошибок на уровне SCTP. В разделе 9 описаны оба варианта завершения работы ассоциаций.

SCTP не поддерживает полуоткрытых состояний (как в TCP), когда одна сторона может передавать данные после того, как другая сторона уже закрыла соединение. Когда любая из конечных точек выполняет процедуру shutdown, на обеих сторонах ассоциации прекращается приём новых данных и доставляются лишь данные из очереди (см. раздел 9).

1.5.2. Упорядоченная доставка в потоках

Термин «поток» (stream) используется в протоколе SCTP для обозначения последовательности пользовательских сообщений, которые доставляются протоколам вышележащих уровней в том же порядке, который сообщения имели в самом потоке. Это отличается от значения термина в контексте TCP, где потоком называют последовательности байтов (в этом документе предполагается, что размер байта составляет 8 битов).

Пользователь SCTP может во время создания ассоциации задать число потоков, поддерживаемых этой ассоциацией. Это значение согласуется с удалённой стороной (см. 5.1.1. Обработка параметров потока). Пользовательские сообщения связываются с номерами потоков (см. примитивы SEND на стр. 50 и RECEIVE на стр. 51). SCTP присваивает порядковые номера в потоке каждому сообщению, полученному протоколом от пользователя SCTP. На приёмной стороне SCTP обеспечивает доставку сообщений пользователю с сохранением их последовательности в данном потоке. В силу того, что один поток может быть заблокирован ожиданием следующего по порядку пользовательского сообщения, в это время возможна доставка сообщений из других потоков.

Протокол SCTP обеспечивает механизм обхода упорядоченной доставки. Пользовательские сообщения, переданные с использованием такого механизма, доставляются пользователю по мере их приёма.

1.5.3. Фрагментация пользовательских данных

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

1.5.4. Подтверждения и предотвращение перегрузки

SCTP присваивает номер TSN каждому фрагменту и нефрагментированному пользовательскому сообщению. Нумерация TSN не зависит от Stream Sequence Number, присваиваемых на уровне потока. Принимающая сторона подтверждает все полученные TSN даже при обнаружении пропуска в номерах. Если нужно повторно передать фрагмент данных пользователя или нефрагментированное сообщение, используется выделенный номер TSN. Такой подход обеспечивает независимую функциональность для гарантии доставки и сохранения порядка сообщений.

Функция подтверждения и предотвращения перегрузки отвечает за повторную передачу пакетов, когда подтверждение о доставке не приходит от получателя вовремя. Повтор передачи связан с предотвращением перегрузки подобно тому, как это сделано для протокола TCP. В разделах 6 и 7 приводится подробное описание протокольных процедур, связанных с выполнением этой функции.

1.5.5. Группировка блоков

Как описано в разделе 3, пакет SCTP, передаваемый на нижележащий уровень, содержит общий заголовок, за которым следует один или несколько информационных блоков (chunk), каждый из них содержит пользовательские данные или управляющую информацию SCTP. Реализация SCTP, поддерживающая группировку, может задержать на стороне отправителя отправку пользовательских сообщений для группировки соответствующих блоков DATA.

Пользователь SCTP может запросить у реализации передачу своих сообщений без задержки, связанной с группировкой. Однако даже при выборе пользователем этой опции реализация SCTP может задерживать передачу по другим причинам (например, связанным с контролем перегрузки или управлением потоком данных) и группировать блоки DATA, если это возможно.

1.5.6. Проверка пакетов

Обязательное поле Verification Tag и 32-битовая контрольная сумма (см. Приложение A. Расчет контрольной суммы CRC32c), передаются в общем заголовке SCTP. Значение Verification Tag выбирается каждой стороной в процессе создания ассоциации. Пакеты, полученные без ожидаемого значения Verification Tag, отбрасываются в целях защиты от атак вслепую с маскированием адресов и избавления от старых пакетов SCTP, оставшихся от предыдущей ассоциации. Контрольная сумма CRC32c помещается отправителем в каждый пакет SCTP для обеспечения дополнительной защиты от повреждения данных в сети. Получатель пакета SCTP с некорректной контрольной суммой CRC32 c отбрасывает такие пакеты без уведомления.

1.5.7. Управление путями

Передающий пакеты SCTP пользователь может манипулировать набором транспортных адресов, используемых для указания получателя пакетов SCTP с помощью примитивов, описанных в разделе 11. Функция управления путями отслеживает доступность с помощью блоков heartbeat, когда другой трафик не позволяет получить достоверных данных о доступности адресов, и сообщает пользователю об изменениях состояния доступности любых адресов транспортного уровня на удалённой стороне. Функция управления путями SCTP выбирает транспортный адрес получателя для каждого исходящего пакета SCTP на основе пользовательских инструкций и текущей информации о доступности желанного получателя. Функция управления путями отвечает также за передачу информации о доступных локальных адресах транспортного уровня партнёру в процессе создания ассоциации и за передачу пользователю SCTP сведений, полученных от партнёра.

При создании ассоциации определяется основной путь (primary path) для каждой конечной точки SCTP, который используется для нормальной передачи пакетов SCTP.

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

Примечание. Функции Path Management и Packet Validation выполняются одновременно, хотя и описаны по отдельности (в реальности эти функции не могут выполняться независимо одна от другой).

1.6. Порядковые номера

Важно помнить, что пространство порядковых номеров TSN ограничено, хотя и достаточно велико. Значения порядковых номеров могут находиться в диапазоне от 0 до 232 – 1. Ввиду конечности пространства TSN все арифметические операции с ними должны осуществляться по модулю 232 – это обеспечит возможность после достижения максимального значения TSN снова перейти к номеру 0. При сравнении значений порядковых номеров следует принимать во внимание цикличность их изменения. Символы =< применительно к TSN означают «меньше или равно» (модуль 232).

При арифметических операциях и сравнении номеров TSN для протокола SCTP следует пользоваться арифметикой порядковых номеров, определённой в [RFC1982] для случая SERIAL_BITS = 32.

Конечным точкам не следует передавать блоки DATA со значением TSN, которое более чем на 231 – 1 превышает начальное значение TSN для текущего окна передачи. Использование таких значений может привести к возникновению проблем при сравнении TSN.

Порядковые номера TSN сбрасываются в 0 при достижении границы 232 – 1. Т. е., следующий блок DATA после блока с TSN = 232 – 1 должен иметь TSN = 0.

Во всех арифметических операциях с порядковыми номерами в потоках (Stream Sequence Number) следует использовать арифметику порядковых номеров, определённую в [RFC1982] для случая SERIAL_BITS = 16. Все прочие операции с порядковыми номерами в данном документе используют обычную арифметику.

1.7. Отличия от RFC 4960

Протокол SCTP был изначально определён в [RFC4960], который данный документ отменяет. Читателям, интересующимся подробностями отличий, рекомендуется прочесть [RFC8540].

В дополнение к этим и последующим редакторским правкам в документ внесены перечисленные ниже изменения.

  • Обновлены ссылки.
  • Улучшен язык описания уровней требований.
  • Примитиву ASSOCIATE разрешено принимать несколько удалённых адресов (см. спецификацию API сокетов).
  • Ссылка на спецификацию Packetization Layer Path MTU Discovery (PLPMTUD) для определения MTU на пути.
  • Описание обработки ICMP перенесено из приложения в основной текст.
  • Удалено приложение с описанием обработки явных уведомлений о перегрузке (ECN).
  • Более точно описана обработка размера пакетов, путём введения PMTU, PMDCS и AMDCS.
  • Добавлено определение управляющего блока (control chunk).
  • Улучшено описание обработки блоков INIT и INIT ACK с непригодными обязательными параметрами.
  • Разрешено применение L > 1 для подсчёта байтов (Appropriate Byte Counting или ABC) при замедленном старте.
  • Явно описана повторная инициализация контроллера перегрузок при смене маршрутов.
  • Улучшена терминология для более ясного представления, что данная спецификация не описывает полносвязную (full mesh) архитектуру.
  • Улучшено описание генерации номеров (Transmission Sequence Number и Stream Sequence Number).
  • Улучшено описание «отречения» (reneging).
  • Больше не требуется изменение Cumulative TSN Ack для увеличения окна перегрузки. Это улучшает согласованность с действиями по предотвращению перегрузки.
  • Улучшено описание State Cookie.
  • Исправлен API для извлечения сообщений при отказах ассоциации.

2. Соглашения о терминах

Ключевые слова должно (MUST), недопустимо (MUST NOT), требуется (REQUIRED), нужно (SHALL), не следует (SHALL NOT), следует (SHOULD), не нужно (SHOULD NOT), рекомендуется (RECOMMENDED), не рекомендуется (NOT RECOMMENDED), возможно (MAY), необязательно (OPTIONAL) в данном документе интерпретируются в соответствии с BCP 14 [RFC2119] [RFC8174] тогда и только тогда, когда они выделены шрифтом, как показано здесь.

3. Формат пакетов SCTP

Пакет SCTP состоит из общего заголовка и блоков (chunk), содержащих пользовательские сообщения или управляющую информацию.

Формат пакетов SCTP показан на рисунке.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Common Header                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          Chunk #1                             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           ...                                 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          Chunk #n                             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Недопустимо группировать INIT, INIT ACK, и SHUTDOWN COMPLETE с другими блоками в один пакет SCTP. Все прочие блоки можно группировать в одном пакете SCTP, пока его размер не превышает значение PMTU. Более подробное описание группировки блоков приводится в параграфе 6.10.

Если пользовательское сообщение не помещается в пакет SCTP, оно может быть разделено на фрагменты с использованием процедуры, описанной в параграфе 6.9.

Все целочисленные поля пакетов SCTP должны передаваться с использованием сетевого порядка байтов, если явно не указан другой порядок.

3.1. Описание полей общего заголовка SCTP

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|     Source Port Number        |     Destination Port Number   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      Verification Tag                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           Checksum                            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Source Port Number – 16 битов (целое число без знака)

Номер порта SCTP, используемого отправителем. Это значение, вместе с IP-адресом отправителя, номером порта получателя и (возможно) IP-адресом получателя, может использоваться на приёмной стороне для идентификации ассоциации, к которой относится пакет. Значение 0 для номера порта недопустимо.

Destination Port Number – 16 битов (целое число без знака)

Номер порта SCTP, в который данный пакет адресован. На приёмной стороне это значение будет использоваться для демультиплексирования пакета SCTP соответствующей конечной точке или приложению. Значение 0 для номера порт недопустимо.

Verification Tag – 32 бита (целое число без знака)

Принимающая сторона использует Verification Tag для проверки отправителя пакета SCTP. На передающей стороне значение поля Verification Tag должно устанавливаться в соответствии со значением Initiate Tag, полученным от партнёра при инициализации ассоциации, за исключением перечисленных ниже случаев.

  • В пакетах, содержащих блок INIT, тег Verification должен быть установлен в 0.
  • В пакетах, содержащих блок SHUTDOWN-COMPLETE с установленным флагом T, значение тега Verification должно копироваться из пакета с блоком SHUTDOWN-ACK.
  • В пакетах, содержащих блок ABORT, тег верификации может быть копией Verification Tag из пакета, вызвавшего передачу блока ABORT. Более подробное описание приведено в параграфах 8.4 и 8.5.

Checksum – 32 бита (целое число без знака)

Это поле содержит контрольную сумму для данного пакета SCTP. Расчёт контрольных сумм описан в параграфе 6.8. Протокол SCTP использует алгоритм CRC32c, описанный в Приложении A.

3.2. Описание поля Chunk

На рисунке показан формат блоков (chunk), передаваемых в пакетах SCTP. Каждый блок содержит поле Chunk Type, зависящие от типа флаги (Chunk Flags), поле размера Chunk Length и поле данных Chunk Value.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   Chunk Type  | Chunk  Flags  |        Chunk Length           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
\                                                               \
/                          Chunk Value                          /
\                                                               \
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Chunk Type – 8 битов (целое число без знака)

Это поле указывает тип блока, содержащегося в поле Chunk Value. Поле типа может содержать значения от 0 до 254. Значение 255 зарезервировано для будущего использования в качестве расширения.

Значения идентификаторов типа приведены в таблице.

Таблица 1. Типы блоков.

ID Тип блока ID Тип блока
0 Пользовательские данные (DATA) 12 Резерв для Explicit Congestion Notification Echo (ECNE)9
1 Инициализация (INIT) 13 Резерв для Congestion Window Reduced (CWR)
2 Подтверждение инициирования (INIT ACK) 14 Окончание работы завершен0 (SHUTDOWN COMPLETE)
3 Выборочное подтверждение (SACK) 15 – 62 Не выделены
4 Запрос Heartbeat (HEARTBEAT) 63 Резерв для определённых IETF расширений
5 Подтверждение Heartbeat (HEARTBEAT ACK) 64 – 126 Не выделены
6 Прерывание (ABORT) 127 Резерв для определённых IETF расширений
7 Завершение работы (SHUTDOWN) 128 – 190 Не выделены
8 Подтверждение завершения (SHUTDOWN ACK) 191 Резерв для определённых IETF расширений
9 Ошибка при операции (ERROR) 192 – 254 Не выделены
10 State Cookie (COOKIE ECHO) 255 Резерв для определённых IETF расширений
11 Подтверждение Cookie (COOKIE ACK)

Коды Chunk Type выбраны таким образом, чтобы 2 старших бита определяли действие, которое следует предпринять конечной точке на приёмной стороне, если Chunk Type не удаётся распознать.

Таблица 2. Обработка неизвестных блоков.

00 Прекратить обработку данного пакета SCTP и отбросить нераспознанный блок и следующие за ним блоки.
01 Прекратить обработку данного пакета SCTP и отбросить нераспознанный блок и следующие за ним блоки, а также сообщить о неопознанном блоке в блоке ERROR с причиной ошибки Unrecognized Parameter Type.
10 Пропустить данный блок и продолжить обработку пакета.
11 Пропустить данный блок и продолжить обработку пакета, а также сообщить о неопознанном блоке в блоке ERROR с причиной ошибки Unrecognized Parameter Type.

Chunk Flags – 8 битов

Использование этих битов зависит от поля Chunk Type. Если в документе явно не указано иное, на передающей стороне все биты следует устанавливать в 0, а на приёмной – игнорировать.

Chunk Length – 16 битов (целое число без знака)

Размер блока в байтах с учётом полей Chunk Type, Chunk Flags, Chunk Length и Chunk Value. Для блоков с пустым Chunk Value поле размера имеет значение 4. Байты заполнения блока в поле Chunk Length не включаются, однако считаются байты заполнения имеющихся параметров переменного размера, за исключением последнего10.

Chunk Value – переменный размер

Поле Chunk Value содержит передаваемую в этом блоке информацию. Формат этого поля и способы его использования зависят от значения Chunk Type.

Общий размер блока (включая поля Type, Length и Value) должен быть кратным 4. Если размер блока не кратен 4, отправитель должен дополнить блок байтами со значением 0, не учитывая эти байты в поле Chunk Length. Заполнение размером долее 3 байтов недопустимо. Получатель должен игнорировать байты заполнения.

Подробное описание используемых в SCTP блоков приводится в параграфе 3.3. Руководства для создания расширений, определяемых IETF, приведены в параграфе 15.1.

3.2.1. Необязательные параметры и поля переменного размера

Блоки управления SCTP включают зависящий от типа блока заголовок с набором полей, за которым может следовать то или иное количество параметров. Необязательные параметры и поля переменной длины указываются в формате TLV11 как описано ниже.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         Parameter Type        |      Parameter Length         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
\                                                               \
/                       Parameter Value                         /
\                                                               \
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Parameter Type – 16 битов (целое число без знака)

16-битовый идентификатор типа параметра и может принимать значения от 0 до 65534.

Значение 65535 зарезервировано для определяемых IETF расширений. Все значения, кроме перечисленных в данном документе при описании конкретных блоков SCTP, зарезервированы для использования IETF.

Parameter Length – 16 битов (целое число без знака)

Размер параметра в байтах с учётом полей Parameter Type, Parameter Length и Parameter Value. Для параметров с пустым полем Parameter Value поле размера имеет значение 4. Размер не учитывает байты заполнения.

Parameter Value – переменный размер

Поле Parameter Value содержит информацию, передаваемую с помощью данного параметра.

Общий размер параметра (включая поля Type, Length и Value) должен быть кратным 4. Если размер параметра не кратен 4, отправитель добавляет в конце (после Parameter Value) байты с нулевым значением. Байты заполнения не учитываются в поле размера. Для отправителя недопустимо использование более 3 байтов заполнения. Получатель должен игнорировать байты заполнения.

Поле Parameter Type кодируется так, чтобы два старших бита определяли действия, предпринимаемые обрабатывающей конечной точкой при обнаружении неизвестного типа параметра.

Таблица 3. Обработка неизвестных параметров.

00 Прекратить обработку данного параметра и следующих за ним параметров в этом блоке.
01 Прекратить обработку данного параметра и следующих за ним параметров в этом блоке, а также сообщить о неопознанном параметре, как указано в параграфе 3.2.2.
10 Пропустить данный параметр и продолжить обработку.
11 Пропустить данный параметр и продолжить обработку пакета, а также сообщить о неопознанном параметре, как указано в параграфе 3.2.2.

Следует отметить, что при получении блока INIT или INIT ACK во всех 4 случаях в ответ передаётся блок INIT ACK или COOKIE ECHO. Для случаев 00 и 01 обработка параметров после неизвестного параметра не производится, но уже обработанные параметры не отбрасываются.

Реальные параметры SCTP определяются в параграфах, посвящённых конкретным блокам SCTP. Правила для определённых IETF расширений параметров определены в параграфе 15.3. Отметим, что тип параметра должен быть уникальным для всех блоков. Например, тип параметра 5 используется для представления адресов IPv4 (см. параграф 3.3.2.1.1). Значение 5 в этом случае резервируется во всех блоках для представления адресов IPv4 и недопустимо его использование в ином смысле в любом другом блоке.

3.2.2. Уведомления о неизвестных параметрах

Если получатель блока INIT обнаруживает неизвестный параметр и сообщает о нем в соответствии с параграфом 3.2.1, он должен указать параметр(ы) в поле Unrecognized Parameter блока INIT ACK, передаваемого в ответ на INIT. Отметим, что если получатель блока INIT не организует ассоциацию (например, по причине нехватки ресурсов), поле Unrecognized Parameter не включается в блок ABORT, передаваемый в ответ на INIT.

Если получатель блока любого другого блока (например, INIT ACK) обнаруживает неизвестные параметры и сообщает о них в соответствии с параграфом 3.2.1, ему следует сгруппировать блок ERROR, содержащий поля Unrecognized Parameter с указанием причины ошибки, с блоком, передаваемым в ответ (например, COOKIE ECHO). Если получатель INIT ACK не группирует блок COOKIE ECHO с блоком ERROR, последний можно передать отдельно, но не раньше получения COOKIE ACK.

В любом случае передачи в пакете блока COOKIE ECHO он должен быть первым блоком.

3.3. Определения блоков SCTP

В этом разделе описываются форматы блоков SCTP различных типов.

3.3.1. Пользовательские данные (DATA) (0)

Для блоков DATA должен использоваться показанный на рисунке формат.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   Type = 0    |  Res  |I|U|B|E|    Length                     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                              TSN                              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|      Stream Identifier S      |   Stream Sequence Number n    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                  Payload Protocol Identifier                  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
\                                                               \
/         User Data (последовательность n потока S)             /
\                                                               \
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Res – 4 бита

Отправителю следует заполнить это поле нулями, а получателю – игнорировать его.

I – 1 бит

Бит I (immediate) отправитель может устанавливать всякий раз, когда может при отправке блока DATA получить преимущество в результате отправки соответствующего блока SACK без задержки (см. раздел 4 в [RFC7053].

U – 1 бит

Флаг разупорядочения, устанавливаемый для блоков DATA, которые могут передаваться без сохранения порядка. Для таких блоков значение поля Stream Sequence Number не задаётся и получатель должен его игнорировать.

После сборки (если она требуется) неупорядоченные блоки DATA должны диспетчеризоваться на вышележащий уровень без попыток восстановления порядка, если флаг U имеет значение 1.

Если неупорядоченное пользовательское сообщение фрагментируется, для каждого фрагмента должен устанавливаться флаг U = 1.

B – 1 бит

Флаг первого фрагмента пользовательского сообщения.

E – 1 бит

Флаг последнего фрагмента пользовательского сообщения.

Length – 16 битов (целое число без знака)

Размер блока DATA в байтах от начала поля типа и до конца поля User Data (без учёта байтов заполнения). Для блока DATA с одним байтом пользовательских данных Length = 17 (17 байтов). Блок DATA с полем User Data размера L будет иметь поле Length со значением (16 + L), где L должно быть больше 0.

TSN – 32 бита (целое число без знака)

Порядковый номер TSN для блока DATA. Значения номеров TSN могут находиться в диапазоне от 0 до 4294967295 (232 – 1). После достижения TSN максимального значения 4294967295 нумерация продолжается с 0.

Stream Identifier S – 16 битов (целое число без знака)

Идентификатор потока, к которому относится блок данных.

Stream Sequence Number n – 16 битов (целое число без знака)

Порядковый номер пользовательских данных в потоке S. Допустимые значения лежат в диапазоне от 0 до 65535.

При фрагментировании пользовательского сообщения протоколом SCTP в каждом фрагмент должен указываться одинаковый порядковый номер в потоке.

Payload Protocol Identifier – 32 бита (целое число без знака)

Заданный приложением или вышележащим протоколом идентификатор протокола данных. SCTP получает идентификатор от вышележащего уровня и передаёт его партнёру. Значение идентификатора не используется протоколом SCTP, но может быть использовано некоторыми сетевыми объектами и приложениями у партнёра для идентификации типа информации, передаваемой в блоке DATA. Это поле должно передаваться даже для фрагментированных блоков DATA (чтобы обеспечить доступность информации для агентов в сети). Отметим, что реализации SCTP не работают с этим полем и за преобразование между сетевым и хостовым порядком байтов в этом поле отвечает вышележащий уровень.

Значение 0 говорит, что протокол вышележащего уровня не указал идентификатор протокола для этого блока.

User Data – переменный размер

Поле переменной длины, содержащее пользовательскую информацию. Реализация протокола должна дополнять поле до 4-байтовой границе путём добавления байтов с нулевым значением. Недопустимо учитывать байты заполнения в поле размера блока. Для отправителя недопустимо использование более 3 байтов заполнения.

В нефрагментированных пользовательских сообщениях должны устанавливаться (1) оба флага B и E. Нулевые значения обоих флагов устанавливаются в средних (не первом и не последнем) фрагментах пакета, как показано в таблице 4.

Таблица 4. Состояния флагов B и E.

B E Описание
1 0 Первый фрагмент.
0 0 Один из средних фрагментов.
0 1 Последний фрагмент.
1 1 Нефрагментированное сообщение.

При фрагментировании пользовательского сообщения на множество блоков получатель использует TSN для сборки сообщения. Это означает, что TSN фрагментов должны устанавливаться в строгом порядке.

TSN в блоках DATA следует строго упорядочивать.

Примечание. Можно применять расширение, описанное в [RFC8260] для снижения блокировки head-of-line при передаче больших пользовательских сообщений.

3.3.2. Инициализация (INIT) (1)

Этот блок используется для создания ассоциации SCTP между парой конечных точек. Формат блока INIT показан на рисунке.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   Type = 1    |  Chunk Flags  |      Chunk Length             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         Initiate Tag                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           Advertised Receiver Window Credit (a_rwnd)          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Number of Outbound Streams   |  Number of Inbound Streams    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          Initial TSN                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
\                                                               \
/     Необязательные параметры и параметры переменной длины     /
\                                                               \
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Блок INIT содержит перечисленные ниже параметры. Если явно не сказано иное, каждый параметр должен включаться в блок INIT в одном экземпляре.

Таблица 5. Параметры фиксированного размера в блоках INIT.

Фиксированные параметры Статус
Initiate Tag Обязательный
Advertised Receiver Window Credit Обязательный
Number of Outbound Streams Обязательный
Number of Inbound Streams Обязательный
Initial TSN Обязательный

Таблица 6. Параметры переменного размера в блоках INIT.

Переменные параметры Статус Тип
IPv4 Address12 Необязательный 5
IPv6 Address1 Необязательный 6
Cookie Preservative Необязательный 9
Reserved for ECN Capable13 Необязательный 32768 (0x8000)
Host Name Address14 Отменён 11
Supported Address Types15 Необязательный 12

Если принят блок INIT со всеми обязательными параметрами, заданными для блока INIT, получателю следует обработать блок INIT и возвратить отправителю INIT ACK. Получатель блока INIT может позднее сгруппировать блок ERROR с блоком COOKIE ACK. Однако ограниченная реализация может возвратить блок ABORT в ответ на блок INIT.

Поле Chunk Flags в INIT является резервным и отправителю следует устанавливать все его биты в 0, а получателю – игнорировать их.

Initiate Tag – 32 бита (целое число без знака)

Получатель INIT (отвечающая сторона) записывает значение параметра Initiate Tag. Это значение должно включаться в поле Verification Tag каждого пакета SCTP, который получатель данного блока INIT будет передавать через эту ассоциацию.

Поле Initiate Tag может содержать любые значения кроме 0. Рекомендации по выбору значений этого тега приводятся в параграфе 5.3.1.

Если в принятом блоке INIT значение Initiate Tag = 0, получатель должен отбрасывать пакет без иных действий.

Advertised Receiver Window Credit (a_rwnd) – 32 бита (целое число без знака)

Размер (в байтах) выделенного буферного пространства, которое отправитель INIT зарезервировал для данной ассоциации.

Для Advertised Receiver Window Credit недопустимы значения меньше 1500.

Получатель блока INIT с a_rwnd < 1500 должен отбросить пакет, ему следует передать в ответ пакет с блоком ABORT и использовать Initiate Tag как Verification Tag, а также недопустимо менять состояние оюбой имеющейся ассоциации.

В течение срока существования ассоциации не следует снижать размер этого буфера (т. е., буфер может быть удалён из ассоциации), однако конечная точка может изменить размер a_rwnd, передаваемого в SACK.

Number of Outbound Streams (OS) – 16 битов (целое число без знака)

Число исходящих потоков, которые отправитель блока INIT желает открыть для данной ассоциации. Для этого параметра недопустимо использование значения 0.

Получатель блока INIT с OS = 0 должен отбросить пакет, ему следует передать в ответ пакет с блоком ABORT и использовать Initiate Tag как Verification Tag, а также недопустимо менять состояние оюбой имеющейся ассоциации.

Number of Inbound Streams (MIS) – 16 битов (целое число без знака)

Максимальное число потоков, которые отправитель данного блока INIT готов принять от партнёра для этой ассоциации16. Использование значений 0 в данном поле недопустимо.

Получатель блока INIT с с MIS = 0 должен отбросить пакет, ему следует передать в ответ пакет с блоком ABORT и использовать Initiate Tag как Verification Tag, а также недопустимо менять состояние оюбой имеющейся ассоциации.

Initial TSN (I-TSN) – 32 бита (целое число без знака)

Определяет начальное значение TSN, которое будет использовать отправитель. Диапазон допустимых значений – от 0 до 4294967295 и следует устанавливать случайное значение из этого диапазона. Для выбора случайного значения можно использовать методы, описанные в [RFC4086].

3.3.2.1. Необязательные параметры и параметры переменного размера в блоке INIT

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

3.3.2.1.1. Параметр IPv4 Address (5)
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|        Type = 5               |      Length = 8               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        IPv4 Address                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

IPv4 Address – 32 бита (целое число без знака)

Адрес IPv4 передающей стороны в двоичном формате.

3.3.2.1.2. Параметр IPv6 Address (6)
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            Type = 6           |          Length = 20          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|                         IPv6 Address                          |
|                                                               |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

IPv6 Address – 128 битов (целое число без знака)

Адрес IPv6 [RFC2460] передающей стороны в двоичном формате.

Отправителю недопустимо использовать адреса отображённые на IPv4 адреса IPv6 [RFC4291], вместо этого следует применять параметр IPv4 Address для адреса IPv4.

Вместе с Source Port Number в общем заголовке SCTP адрес IPv4 или IPv6 определяет адрес транспортного уровня, который отправитель блока INIT будет поддерживать для создаваемой ассоциации. Т. е., этот IP-адрес в течении срока действия данной ассоциации может появляться в поле отправителя дейтаграмм IP, передаваемых отправителем данного блока INIT, и может использоваться в качестве IP-адреса получателя в дейтаграммах, передаваемых получателем данного блока INIT.

В блоке INIT можно указывать более одного адреса IP, если отправитель INIT является многодомным хостом. Кроме того, многодомные хосты могут быть подключены к разнотипным сетям и в блоках INIT могут указываться одновременно адреса IPv4 и IPv6.

Если INIT содержит хотя бы один параметр IP Address, адрес отправителя в дейтаграмме, содержащей блок INIT, и любые адреса, указанные в INIT, могут использоваться партнёром при ответе в качестве адреса получателя. Если INIT не содержит параметров IP Address, получившая блок INIT конечная точка должна использовать адрес отправителя в заголовке дейтаграммы IP, содержащей блок INIT, как единственный адрес партнёра в данной ассоциации.

Отметим, что отсутствие параметров IP Address в блоках INIT и INIT ACK упрощает организацию ассоциаций при работе через системы трансляции адресов (Network Address Translation или NAT).

3.3.2.1.3. Параметр Cookie Preservative (9)

Отправителю блока INIT следует использовать этот параметр для того, чтобы предложить получателю INIT увеличение срока действия State Cookie.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          Type = 9             |          Length = 8           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         Suggested Cookie Life-span Increment (мсек.)          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Suggested Cookie Life-Span Increment – 32 бита (целое число без знака)

Показывает получателю размер увеличения срока действия cookie в миллисекундах.

Этот необязательный параметр отправителю следует добавлять в блок INIT при попытке создания ассоциации после отказа в предыдущей попытке по причине ошибки в работе stale cookie. Получатель может проигнорировать предложенное увеличение срока действия cookie в соответствии со своей политикой безопасности.

3.3.2.1.4. Параметр Host Name Address (11)

Отправителю блока INIT или INIT ACK недопустимо включать этот параметр, поскольку его использование отменено. Получатель блока INIT или INIT ACK с параметром Host Name Address должен передать блок ABORT и может включить в него причину Unresolvable Address.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          Type = 11            |          Length               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/                          Host Name                            /
\                                                               \
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Host Name – переменный размер

Это поле содержит имя хоста с использованием синтаксиса, определённого в параграфе 2.1 RFC1123 [RFC1123]. Метод преобразования имени в адрес выходит за рамки спецификации протокола SCTP.

Имя хоста должно содержать хотя бы один завершающий null-символ, который учитывается в поле размера.

3.3.2.1.5. Параметр Supported Address Types (12)
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          Type = 12            |          Length               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|        Address Type #1        |        Address Type #2        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                            ......                             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Отправитель блока INIT использует этот параметр для перечисления всех поддерживаемых им типов адресов.

Address Type – 16 битов (целое число без знака)

В этом поле указываются типы адреса из соответствующих TLV (например, IPv4 = 5, IPv6 = 6). Значение, указывающее параметр Host Name Address, недопустимо использовать при передачи, а при получении оно должно игнорироваться.

3.3.3. Подтверждение инициализации (INIT ACK) (2)

Блок INIT ACK используется для подтверждения инициирования ассоциации SCTP. Формат блока показан на рисунке.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   Type = 2    |  Chunk Flags  |      Chunk Length             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         Initiate Tag                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|              Advertised Receiver Window Credit                |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Number of Outbound Streams   |  Number of Inbound Streams    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          Initial TSN                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
\                                                               \
/     Необязательные параметры и параметры переменной длины     /
\                                                               \
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Параметры INIT ACK форматируются подобно параметрам блока INIT и показаны в таблицах ниже.

Таблица 7. Параметры фиксированного размера в блоках INIT ACK.

Фиксированные параметры Статус
Initiate Tag Обязательный
Advertised Receiver Window Credit Обязательный
Number of Outbound Streams Обязательный
Number of Inbound Streams Обязательный
Initial TSN Обязательный

Блоки INIT ACK содержат два дополнительных параметра – State Cookie и Unrecognized Parameter.

Таблица 8. Параметры переменного размера в блоках INIT ACK.

Переменные параметры Статус Тип
State Cookie Обязательный 7
IPv4 Address17 Необязательный 5
IPv6 Address1 Необязательный 6
Unrecognized Parameter Необязательный 8
Reserved for ECN Capable18 Необязательный 32768 (0x8000)
Host Name Address19 Отменён 11

Поле Chunk Flags в блоках INIT ACK является резервным, в нем следует устанавливать 0 при передаче и игнорировать при получении.

Initiate Tag – 32 бита (целое число без знака)

Получатель блока INIT ACK записывает значение параметра Initiate Tag. Это значение должно помещаться в поле Verification Tag каждого пакета SCTP, который получатель INIT ACK будет передавать в данной ассоциации.

Для Initiate Tag недопустимо использование значения 0. Выбор значений параметра Initiate Tag рассматривается в параграфе 5.3.1.

Если в полученном блоке INIT ACK параметр Initiate Tag = 0, приёмная сторона должна отбросить TCB и ей следует передать блок ABORT с установленным флагом T. Если такой блок INIT ACK получен в состоянии, отличном от CLOSED и COOKIE-WAIT, его следует просто отбросить (см. параграф 5.2.3).

Advertised Receiver Window Credit (a_rwnd) – 32 бита (целое число без знака)

Это значение указывает размер буфера (в байтах), выделенного отправителем INIT ACK для данной ассоциации.

Недопустимо устанавливать для этого параметра значение < 1500.

Получатель блока INIT ACK с a_rwnd < 1500 должен отбросить пакет, следует передать блок ABORT и использовать Initiate Tag в качестве Verification Tag. Менять состояние ассоциации недопустимо.

В течение срока действия ассоциации не следует уменьшать размер буфера (т. е., выделенный буфер не удаляется из ассоциациеи), однако конечная точка может изменить значение a_rwnd в блоках SACK.

Number of Outbound Streams (OS) – 16 битов (целое число без знака)

Число исходящих потоков, которые отправитель INIT ACK желает создать для данной ассоциации. Недопустимо устанавливать для этого параметра значение 0, недопустимо также устанавливать значение, превышающее значение MIS, переданное в блоке INIT.

Если конечная точка в состоянии COOKIE-WAIT получает INIT ACK с параметром OS = 0, она должна отбросить TCB и следует передать блок ABORT. Если такой блок INIT ACK получен в состоянии, отличном от CLOSED и COOKIE-WAIT, его следует просто отбросить (см. параграф 5.2.3).

Number of Inbound Streams (MIS) – 16 битов (целое число без знака)

Максимальное число потоков, которые отправитель INIT ACK позволяет создать удалённому партнёру в данной ассоциации20. Недопустимо использование нулевого значения для этого параметра.

Если конечная точка в состоянии COOKIE-WAIT получает INIT ACK с параметром MIS = 0, она должна отбросить TCB и следует передать блок ABORT. Если такой блок INIT ACK получен в состоянии, отличном от CLOSED и COOKIE-WAIT, его следует просто отбросить (см. параграф 5.2.3).

Initial TSN (I-TSN) – 32 бита (целое число без знака)

Начальный номер TSN, который отправитель INIT ACK будет использовать. Корректные значения лежат в диапазоне от 0 до 4294967295 и следует устанавливать случайное значение из этого диапазона. Для выбора случайного значения можно использовать методы, описанные в [RFC4086].

Примечание для разработчиков. Реализации должны быть готовы к получению INIT ACK достаточно большого (более 1500 байтов) размера по причине переменного размера State Cookie и списка адресов. Например, если отвечающая на INIT сторона имеет 1000 адресов IPv4, которые она желает сообщить, для них потребуется не менее 8000 байтов в блоке INIT ACK.

Если принят блок INIT ACK со всеми обязательными для него параметрами, получателю следует обработать блок INIT ACK и передать в ответ COOKIE ECHO. Получатель INIT ACK может группировать блок ERROR с блоком COOKIE ECHO. Однако ограниченные реализации могут передавать блок ABORT в ответ на INIT ACK.

Вместе с параметром Source Port Number в общем заголовке SCTP параметр IP Address в INIT ACK указывает получателю INIT ACK адрес транспортного уровня, который отправитель блока INIT ACK будет поддерживать в течение срока действия создаваемой ассоциации.

Если INIT ACK содержит хотя бы один параметр IP Address, указанные в нем адреса вместе с адресом отправителя в заголовке дейтаграммы IP, содержащей INIT ACK, могут использоваться получателем INIT ACK блока в качестве адресов получателя для этой ассоциации. Если в INIT ACK нет параметра IP Address, получатель блока INIT ACK должен использовать адрес отправителя содержащей этот блок дейтаграммы IP в качестве единственного адреса получателя для этой ассоциации.

Параметры State Cookie и Unrecognized Parameters используют формат TLV в соответствии с определением параграфа 3.2.1 и описаны ниже. Остальные поля соответствуют одноимённым полям блока INIT.

3.3.3.1. Необязательные параметры и параметры переменной длины в INIT ACK

Для State Cookie и Unrecognized Parameters применяется формат TLV, как определено в параграфе 3.2.1 и описано ниже. Параметр IPv4 Address описан в параграфе 3.3.2.1.1, а IPv6 Address – в 3.3.2.1.2. Параметр Host Name Address, описанный в параграфе 3.3.2.1.4, недопустимо включать в блок INIT ACK. Все поля TLV должны размещаться после полей фиксированного размера (они определены в предыдущем параграфе).

3.3.3.1.1. Параметр State Cookie (7)

0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type = 7 | Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / Cookie / \ \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Cookie – переменный размер

Значение этого параметра должно включать всю необходимую информацию о состоянии и параметрах, требуемую отправителю данного блока INIT ACK для создания ассоциации, а также код аутентификации сообщения (Message Authentication Code или MAC). Определение State Cookie дано в параграфе 5.1.3.

3.3.3.1.2. Параметр Unrecognized Parameter (8)

0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type = 8 | Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / Unrecognized Parameter / \ \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Unrecognized Parameter – переменный размер

Это поле содержит нераспознанный параметр (полный TLV), скопированный из блока INIT.

3.3.4. Селективное подтверждение (SACK) (3)

Этот блок передаётся партнёру для подтверждения приёма блоков DATA и информирования партнёра о пропусках в порядковых номерах блоков DATA, представленных в TSN.

Блок SACK должен включать поля Cumulative TSN Ack, Advertised Receiver Window Credit (a_rwnd), Number of Gap Ack Blocks и Number of Duplicate TSNs.

По определению поле Cumulative TSN Ack содержит значение последнего номера TSN, полученного до того, как была нарушена последовательность принятых TSN. Следующее за этим значение TSN (на 1 больше) ещё не получено стороной, передающей SACK. Этот параметр, следовательно, подтверждает доставку всех TSN, номера которых не превышают значение поля.

Обработка a_rwnd получателем SACK рассмотрена в параграфе 6.2.1

SACK может также содержать параметры Gap Ack Block, каждый из которых подтверждает последовательность TSN, полученных после прерывания основной последовательности номеров TSN. Блокам Gap Ack Block следует быть изолированными, т. е. TSN непосредственно перед и сразу после Gap Ack Block не получены. По определению все TSN, подтверждённые Gap Ack Block, имеют значения, превышающие Cumulative TSN Ack.

0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type = 3 |Chunk Flags | Chunk Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Cumulative TSN Ack | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Advertised Receiver Window Credit (a_rwnd) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Number of Gap Ack Blocks = N | Number of Duplicate TSNs = X | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Gap Ack Block #1 Start | Gap Ack Block #1 End | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / \ … \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Gap Ack Block #N Start | Gap Ack Block #N End | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Duplicate TSN 1 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / \ … \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Duplicate TSN X | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Chunk Flags – 8 битов

Заполняется нулями на передающей стороне и игнорируется на приёмной.

Cumulative TSN Ack – 32 бита (целое число без знака)

Наибольшее значение TSN, такое что все значения, не превышающие его, уже получены, а следующее не получено. Если блоков DATA ещё не получено, это поле содержит партнерское значение Initial TSN – 1.

Advertised Receiver Window Credit (a_rwnd) – 32 бита (целое число без знака)

Обновлённое значение размера (в байтах) приёмного буфера на стороне отправителя данного блока SACK (см. параграф 6.2.1).

Number of Gap Ack Blocks – 16 битов (целое число без знака)

Число параметров Gap Ack Block, включённых в SACK.

Number of Duplicate TSNs – 16 битов

Число дубликатов TSN, полученных конечной точкой. Каждый дубликат TSN указывается в последующем списке Gap Ack Block.

Блоки Gap Ack

Эти поля содержат параметры Gap Ack Block, число которых задано значением поля Number of Gap Ack Blocks. Все блоки DATA с номерами TSN не меньше Cumulative TSN Ack + Gap Ack Block Start и не больше Cumulative TSN Ack + Gap Ack Block End из каждого Gap Ack Block предполагаются принятыми без ошибок.

Gap Ack Block Start – 16 битов (целое число без знака)

Показывает стартовое смещение TSN данного Gap Ack Block. Для расчёта реального номера TSN это смещение добавляется к значению параметра Cumulative TSN Ack. Рассчитанное таким способом значение TSN указывает первый номер TSN в данном Gap Ack Block, который был получен.

Gap Ack Block End – 16 битов (целое число без знака)

Показывает финишное смещение TSN данного Gap Ack Block. Для расчёта реального номера TSN это смещение добавляется к значению параметра Cumulative TSN Ack. Рассчитанное таким способом значение TSN указывает последний номер TSN в данном Gap Ack Block для полученного блока DATA.

Предположим для примера, что недавно полученные блоки DATA в момент принятия решения о передаче SACK образуют последовательность, показанную на рисунке.

———- | TSN=17 | ———- | | <- не получен ———- | TSN=15 | ———- | TSN=14 | ———- | | <- не получен ———- | TSN=12 | ———- | TSN=11 | ———- | TSN=10 | ———-
Тогда часть блока SACK должна включать поля, показанные на следующем рисунке (предполагается, что новое значение a_rwnd = 4660).

+——————————–+ | Cumulative TSN Ack = 12 | +——————————–+ | a_rwnd = 4660 | +—————-+—————+ | num of block=2 | num of dup=0 | +—————-+—————+ |block #1 strt=2 |block #1 end=3 | +—————-+—————+ |block #2 strt=5 |block #2 end=5 | +—————-+—————+

Duplicate TSN – 32 бита (целое число без знака)

Показывает количество случаев, когда номер TSN был принят как дубликат, с момента передачи последнего блока SACK. При получении каждого дубликата TSN (до момента передачи SACK) этот дубликат добавляется в список. Счётчик дубликатов сбрасывается в 0 после отправки каждого блока SACK.

Например, если получатель принял TSN 19 трижды, номер 19 будет указан два раза в блоке SACK. После отправки SACK, если TSN 19 будет принят снова, он будет указан в списке следующего блока SACK.

3.3.5. Запрос Heartbeat (HEARTBEAT) (4)

Конечной точке следует передавать блок HEARTBEAT (HB) своему партнёру для проверки его доступности через конкретный транспортный адрес, заданный для данной ассоциации.

Поле параметров содержит Heartbeat Information – не анализируемую (opaque) структуру данных переменного размера, понятную только отправителю.

0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type = 4 | Chunk Flags | Heartbeat Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ \ \ / Heartbeat Information TLV (переменный размер) / \ \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Chunk Flags – 8 битов

Устанавливается в 0 на передающей стороне и игнорируется на приёмной.

Heartbeat Length – 16 битов (целое число без знака)

Размер блока в байтах с учётом заголовка и поля Heartbeat Information.

Heartbeat Information – переменный размер

Параметр переменного размера, который использует формат, описанный в параграфе 3.2.1.

Таблица 9. Параметры переменного размера в блоке HEARTBEAT.

Параметр Статус Тип
Heartbeat Info Обязательный 1

0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Heartbeat Info Type=1 | HB Info Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / Sender-Specific Heartbeat Info / \ \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

В поле Sender-Specific Heartbeat Info обычно следует включать информацию о текущем времени отправителя на момент передачи данного блока HEARTBEAT и транспортный адрес получателя этого блока (см. параграф 8.3). Эта информация просто «отражается» получателем в его блоке HEARTBEAT ACK (см. параграф 3.3.6). Отметим также, что сообщения HEARTBEAT служат для проверки доступности и верификации пути (см. параграф 5.4). При использовании блока HEARTBEAT для проверки пути он должен включать случайное значение не менее 64 битов (см. рекомендации по созданию случайных чисел в [RFC4086]).

3.3.6. Подтверждение Heartbeat (HEARTBEAT ACK) (5)

Конечная точка должна передавать такой блок в ответ на запрос HEARTBEAT (см. параграф 8.3). Пакет с блоком HEARTBEAT ACK всегда передаётся по тому адресу IP, который был указан в заголовке дейтаграммы, содержавшей запрос HEARTBEAT, на который передаётся отклик.

Поле параметра содержит «непрозрачную» структуру данных с переменным размером.

0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type = 5 | Chunk Flags | Heartbeat Ack Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ \ \ / Heartbeat Information TLV (переменный размер) / \ \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Chunk Flags – 8 битов

Устанавливается в 0 на передающей стороне и игнорируется на приёмной.

Heartbeat Length – 16 битов (целое число без знака)

Задаёт размер блока в байтах с учётом заголовка и поля Heartbeat Information.

Heartbeat Information – переменный размер

Это поле должно содержать параметр Heartbeat Information из запроса Heartbeat, на который отвечает данный блок Heartbeat Acknowledgement.

Таблица 10. Параметры переменного размера в блоке HEARTBEAT ACK.

Параметр Статус Тип
Heartbeat Info Обязательный 1

3.3.7. Разрыв ассоциации (ABORT) (6)

Блок ABORT передаётся партнёру для разрыва ассоциации. Блок ABORT может содержать параметры Error Cause, информирующие партнёра о причинах разрыва ассоциации. Недопустимо группировать блоки DATA с блоком ABORT. Блоки управления (кроме INIT, INIT ACK и SHUTDOWN COMPLETE) могут группироваться с ABORT, но эти блоки должны размещаться перед блоком ABORT в пакете SCTP, поскольку в противном случае получатель проигнорирует их.

Если конечная точка получает блок ABORT с некорректным форматом или TCB не найден, такой блок должен быть просто отброшен. Более того, в некоторых случаях для получившей такой блок ABORT конечной точки недопустимо передавать в ответ свой блок ABORT.

0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type = 6 |Reserved |T| Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ \ \ / Причины ошибок (Error Cause) / \ \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Chunk Flags – 8 битов

Reserved – 7 битов

Устанавливается в 0 на передающей стороне и игнорируется на приёмной.

T – 1 бит

Бит T сбрасывается в 0, если отправитель заполнил поле Verification Tag, ожидаемое партнёром. Если в Verification Tag используется «отражённое» значение, должно устанавливаться T = 1. Отражение означает, что переданное значение Verification Tag совпадает с принятым.

Length – 16 битов (целое число без знака)

Указывает размер блока в байтах с учётом заголовка и всех полей Error Cause.

Определения причин ошибки (Error Cause) приведены в параграфе 3.3.10.

Примечание. Для проверки этого типа блоков применяются специальные правила, описанные в параграфе 8.5.1.

3.3.8. Завершение ассоциации (SHUTDOWN) (7)

Конечная точка ассоциации должна использовать этот блок для аккуратного завершения работы ассоциации. Формат блока описан ниже.

0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type = 7 | Chunk Flags | Length = 8 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Cumulative TSN Ack | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Chunk Flags – 8 битов

Устанавливается в 0 на передающей стороне и игнорируется на приёмной.

Length – 16 битов (целое число без знака)

Показывает размер параметра и имеет значение 8.

Cumulative TSN Ack – 32 бита (целое число без знака)

Этот параметр содержит номер последнего TSN, принятого без пропусков в нумерации.

Примечание. Поскольку блок SHUTDOWN не содержит параметров Gap Ack Block, он не может служить подтверждением TSN, принятых с нарушением порядка. В блоках SACK отсутствие Gap Ack Block, которые были указаны в предыдущих сообщениях, показывает, что получатель данных отказался от соответствующих блоков DATA.

Поскольку SHUTDOWN не содержит Gap Ack Block, получателю блока SHUTDOWN недопустимо интерпретировать отсутствие Gap Ack Block как отказ (см. параграф 6.2).

Отправитель блока SHUTDOWN может сгруппировать его с блоком SACK для указания пропусков в полученных TSN.

3.3.9. Подтверждение закрытия ассоциации (SHUTDOWN ACK) (8)

Этот блок должен использоваться для подтверждения приёма блока SHUTDOWN при завершении процесса закрытия, описанного в параграфе 9.2.

Блок SHUTDOWN ACK не содержит параметров.

0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type = 8 |Chunk Flags | Length = 4 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Chunk Flags – 8 битов

Устанавливается в 0 на передающей стороне и игнорируется на приёмной.

3.3.10. Ошибка при работе (ERROR) (9)

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

0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Type = 9 | Chunk Flags | Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ \ \ / Одно или несколько полей Error Cause / \ \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Chunk Flags – 8 битов

Устанавливается в 0 на передающей стороне и игнорируется на приёмной.

Length – 16 битов (целое число без знака)

Указывает размер блока в байтах с учётом заголовка и всех полей Error Cause.

Причины ошибок указываются как параметры переменного размера в соответствии с параграфом 3.2.1.

0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Cause Code | Cause Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / Cause-Specific Information / \ \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Cause Code – 16 битов (целое число без знака)

Указывает код причины, которая вызвала передачу блока.

Таблица 11. Коды причин.

Код Описание Код Описание
1 Некорректный идентификатор потока 8 Нераспознанные параметры
2 Отсутствие обязательного параметра 9 Отсутствие пользовательских данных
3 Ошибка Stale Cookie 10 Получение Cookie в процессе закрытия
4 Нехватка ресурсов 11 Перезапуск ассоциации с новыми адресами
5 Не удалось преобразовать адрес 12 Инициированный пользователем разрыв
6 Нераспознанный тип блока 13 Протокольное нарушение
7 Некорректный обязательный параметр

Cause Length – 16 битов (целое число без знака)

Указывает размер параметра в байтах с учётом полей Cause Code, Cause Length и Cause-Specific Information

Cause-Specific Information – переменный размер

В этом поле указываются сведения об ошибке.

Причины ошибок SCTP рассматриваются в параграфах 3.3.10.1 – 3.3.10.13. Рекомендации по определению новых типов ошибок для IETF даны в параграфе 15.4.

3.3.10.1. Неприемлемый идентификатор потока (1)

Показывает, что конечная точка получила блок DATA, переданный в несуществующий поток.

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Cause Code=1 | Cause Length=8 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Stream Identifier | (Reserved) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Stream Identifier – 16 битов (целое число без знака)

Значение Stream Identifier из блока DATA, вызвавшего ошибку.

Reserved – 16 битов

Зарезервированное поле. Устанавливается в 0 на передающей стороне и игнорируется на приёмной.

3.3.10.2. Отсутствует обязательный параметр (2)

Говорит об отсутствии одного или нескольких обязательных параметров TLV в принятом блоке INIT или INIT ACK.

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Cause Code=2 | Cause Length=8+N*2 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Number of missing params=N | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Missing Param Type #1 | Missing Param Type #2 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Missing Param Type #N-1 | Missing Param Type #N | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Number of Missing params – 32 бита (целое число без знака)

Число отсутствующих параметров, перечисленных в Cause-Specific Information (поля Missing Param Type).

Missing Param Type – 16 битов (целое число без знака)

Каждое поле содержит пропущенный обязательный параметр.

3.3.10.3. Ошибка Stale Cookie (3)

Говорит о получении корректного значения State Cookie с истекшим сроком.

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Cause Code=3 | Cause Length=8 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Measure of Staleness (мксек.) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Measure of Staleness – 32 бита (целое число без знака)

В этом поле указывается разница между текущим временем и временем окончания срока действия State Cookie (в микросекундах с округлением).

Отправитель этого сообщения может указать время, прошедшее после завершения срока действия State Cookie, отличным от нуля значением поля Measure of Staleness. Если отправитель не хочет передавать эти сведения, ему следует установить нулевое значение в поле Measure of Staleness.

3.3.10.4. Нехватка ресурсов (4)

Указывает нехватку ресурсов у отправителя и передаётся обычно в комбинации с блоком ABORT или в нем.

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Cause Code=4 | Cause Length=4 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

3.3.10.5. Нераспознаваемый адрес (5)

Говорит о том, что отправителю не удалось распознать указанный адресный параметр (например, отправитель не поддерживает этот тип адресов) и передаётся обычно в комбинации с блоком ABORT или в нем.

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Cause Code=5 | Cause Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / Unresolvable Address / \ \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Unresolvable Address – переменный размер

Поле Unresolvable Address содержит полное значение параметра TLV, задающего адрес (или параметра Host Name), который не удалось распознать, или имя хоста.

3.3.10.6. Не распознан тип блока (6)

Эта информация передаётся отправителю блока, если получатель не смог определить тип блока и два старших бита поля Chunk Type имеют значение 01 или 11.

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Cause Code=6 | Cause Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / Unrecognized Chunk / \ \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Unrecognized Chunk – переменный размер

Поле Unrecognized Chunk содержит нераспознанный блок из пакета SCTP, включая поля Chunk Type, Chunk Flags и Chunk Length.

3.3.10.7. Недействительный обязательный параметр (7)

Это сообщение передаётся отправителю блока INIT или INIT ACK, когда один или несколько обязательных параметров имеют недействительные значения.