RFC 4340 (Часть 2)

Please enter banners and links.

image_print

Часть 1

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

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

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

Фаза организации соединения DCCP включает трехэтапное согласование – клиент передает начальный запрос DCCP-Request, сервер отвечает на него пакетом DCCP-Response и клиент в заключение передает серверу пакет подтверждения (обычно DCCP-Ack или DCCP-DataAck). Клиент переходит из состояния REQUEST в состояние PARTOPEN, а потом в состояние OPEN; сервер переходит из состояния LISTEN сначала в состояние RESPOND, а потом в состояние OPEN.

 Состояние клиента                      Состояние сервера
     CLOSED                                   LISTEN
1.   REQUEST   -->       Request        -->
2.             <--       Response       <--   RESPOND
3.   PARTOPEN  -->     Ack, DataAck     -->
4.             <--  Data, Ack, DataAck  <--   OPEN
5.   OPEN      <->  Data, Ack, DataAck  <->   OPEN

8.1.1. Запрос клиента

Когда клиент решает организовать соединения, он переходит в состояние REQUEST, выбирает начальный порядковый номер (параграф 7.2) и передает пакет DCCP-Request, используя выбранный порядковый номер для данного сервера.

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

Клиенту в состоянии REQUEST следует использовать таймер для экспоненциального увеличения интервала передачи повторных пакетов DCCP-Request при отсутствии отклика от сервера. Первый повтор следует передавать приблизительно через 1 секунду и далее экспоненциально увеличивать интервал повтора не менее, чем до 64 секунд. Конечная точка может также использовать стратегию передачи повторов, принятую для пакетов TCP SYN. В каждом новом пакет DCCP-Request порядковый номер должен увеличиваться на 1 и все пакеты должны содержать такие же значения в поле Service Code и поле данных приложения, как и в исходном запросе DCCP-Request.

Клиент может прервать передачу запросов DCCP-Request по истечении того или иного времени (например, 3 минут). В таких случаях следует передать серверу пакет DCCP-Reset с Reset Code 2, Aborted для сброса состояния сервера в тех случаях, когда один или несколько запросов все-таки были доставлены серверу. Клиент в состоянии REQUEST никогда не получает начальный порядковый номер от своего партнера, поэтому в пакете DCCP-Reset должно быть установлено Acknowledgement Number = 0.

Клиент переходит из состояния REQUEST в состояние PARTOPEN при получении от сервера пакета DCCP-Response.

8.1.2. Коды сервиса

Каждый пакет DCCP-Request содержит 32-битовый код сервиса, определяющий службу прикладного уровня, к который пытается подключиться клиент. Значения Service Code должны соответствовать прикладным службам и протоколам. Примерами могут служить коды сервиса для организации соединений SIP или аудио-сервиса RTP. Промежуточные устройства могут использовать поля Service Code для идентификации приложений, работающих через нестандартный порт (предполагается, что заголовок DCCP не зашифрован).

Конечные точки должны связывать значение Service Code с каждым сокетом DCCP, открытым активно или пассивно. Приложения, в общем случае, будут предоставлять значения Service Code. Каждый активный сокет должен иметь в точности одно значение Service Code. Пассивные сокеты могут (по выбору приложения) связываться с несколькими значениями кодов сервиса. Это позволяет множеству приложений или разным версиям одного приложения прослушивать один порт с использованием значения Service Code для выбора нужного приложения. Если пакет DCCP-Request содержит значение Service Code, которое не соответствует ни одному из кодов сервиса для данного порта, сервер должен отвергнуть запрос, передавая пакет DCCP-Reset с Reset Code 8, Bad Service Code. Промежуточное устройство также может передать такой пакет DCCP-Reset в ответ на запросы, значение Service Code в которых представляется неподходящим.

Значения Service Code не предназначены для исключительного использования DCCP и распределяются агентством IANA. В соответствии с правилами [RFC2434] большинство значений Service Code выделяется в порядке поступления запросов1 с соблюдением приведенных здесь рекомендаций.

  • Значения Service Code выделяются по одному или небольшими блоками. Для выделения значения Service Code требуется краткое описание сервиса на английском языке, но спецификаций, предложенных стандартов или чего-то иного не требуется. IANA поддерживает связь значений Service Code с соответствующими описаниями.
  • Пользователи запрашивают конкретные значения кода сервиса. Мы предлагаем представлять код запрашиваемого сервиса с использованием формата «SC:», описанного ниже. Таким образом Frobodyne Plotz Protocol может соответствовать Service Code = 17178548426 или «SC:fdpz». Каноническая интерпретация поля Service Code является числовой.
  • Для значений Service Code, байты которых входят в набор {32, 45-57, 65-90}, при выделении значений используется процедура Specification Required2 (т. е., такие значения Service Code используются для международных стандартов, спецификаций со статусом standards-track, IETF и в иных случаях). Указанный набор содержит символы цифр, пробела, знака подчеркивания, ‘-‘, ‘.’ и ‘/’ в коде ASCII.
  • Значения Service Code со старшим байтом 63 (ASCII-код символа ?) зарезервированы для частного использования (Private Use).
  • Значение Service Code = 0 представляет отсутствие значимого кода обслуживания и его недопустимо выделять для иного применения.
  • Значение 4294967295 обозначает некорректный код обслуживания. Серверы должны отвергать все пакеты DCCP-Request с таким значением Service Code, передавая в ответ на них пакет DCCP-Reset с Reset Code 8, Bad Service Code.

Эта схема распределения значений Service Code основана на распределении 4-байтовых идентификаторов ресурсов Macintosh, блоков PNG, а также таблиц TrueType и OpenType.

В текстовом представлении рекомендуется указывать значения Service Code в одной из трех форм с префиксом (в коде ASCII) SC, за которым следует двоеточие «:» или знак равенства «=». Ниже описана интерпретация этих форм.

SC:

Показывает код сервиса, представляемый с использованием подмножества символов ASCII. После двоеточия указывается от 1 до 4 символов, которые могут быть буквами, цифрами и знаками «-_+.*/?@» (не включая символы кавычек). Десятичные коды этих символов относятся к набору {42-43, 45-57, 63-90, 95, 97-122}. Значение Service Code рассчитывается путем дополнения строки пробелами (символ с кодом 32) справа до 4 байтов и интерпретации полученной строки как 32-битового целого числа со старшим байтом в начале.

SC=

Задает значение Service Code в форме десятичного числа. После знака равенства может указываться любое количество десятичных цифр, которое задает код обслуживания. Значение Service Code = 4294967294 является некорректным.

SC=x или SC=X

Задает значение Service Code в форме шестнадцатеричного числа. После символа «x» или «X» может указываться любое количество шестнадцатеричных цифр (регистр символов не имеет значения), задающих код обслуживания. Значение Service Code = 4294967294 является некорректным.

Таким образом, Service Code со значением 1717858426 можно представить в форме SC:fdpz, SC=1717858426 или SC=x6664707A.

8.1.3. Отклик сервера

Во второй фазе трехэтапного согласования сервер переходит из состояния LISTEN в состояние RESPOND и передает клиенту сообщение DCCP-Response. В этой фазе сервер зачастую будет задавать признаки, которые он хочет использовать, из числа запрошенных клиентом признаков или в дополнение к ним. Среди опций указывается и механизм контроля насыщения, который сервер предполагает использовать.

Сервер может ответить на пакет DCCP-Request пакетом DCCP-Reset, означающим отказ в соединении. Подходящие для этого случая значения Reset Code включают 7, Connection Refused (когда значение Destination Port в пакете DCCP-Request не соответствует порту DCCP, открытому для прослушивания), 8, Bad Service Code (значение Service Code в пакете DCCP-Request не соответствует коду сервиса, зарегистрированному для порта) и 9, Too Busy (когда сервер слишком занят и не может ответить на запрос). Серверу следует ограничивать скорость, с которой могут генерироваться пакеты отказа (например, не более 1024 отказов в секунду).

Серверу не следует повторять передачу пакетов DCCP-Response, поскольку при отсутствии отклика клиент будет повторно передавать пакет DCCP-Request (отметим, что «повторный» пакет DCCP-Request будет отличаться от исходного, по крайней мере, порядковым номером, что позволяет серверу отличать повтор пакетов от их дублирования в сети). Сервер будет детектировать принадлежность повторных пакетов DCCP-Request к существующему соединению, используя номера портов отправителя и получателя. Каждый корректный пакет DCCP-Request, принятый сервером в состоянии RESPOND, должен вызывать генерацию нового ответного пакета DCCP-Response. В каждом новом пакете DCCP-Response поле Sequence Number должно увеличиваться на 1, а пакет должен включать те же данные приложения, которые были включены в исходный пакет DCCP-Response.

Для сервера недопустимо принимать более одного элемента данных приложения в пакете DCCP-Request для каждого соединения. В частности, для пакета DCCP-Response, передаваемого в ответ на повторный пакет DCCP-Request с данными приложения, следует устанавливать опцию Data Dropped, которая говорит об отбрасывании данных из повторного пакета DCCP-Request с Drop Code 0, Protocol Constraints. Исходный пакет DCCP-Request также следует указывать в опции Data Dropped как Normal Block (если сервер принял данные или данных не было) или Drop Code 0, Drop Block (если сервер отказался от приема этих данных).

Опции Data Dropped и Init Cookie полезны, в частности, для пакетов DCCP-Response (параграфы 11.7 и 8.1.4).

Сервер переходит из состояния RESPOND в состояние OPEN при получении от клиента корректного пакета DCCP-Ack, завершающего трехэтапное согласование. Сервер может также перейти из состояния RESPOND в состояние CLOSED по тайм-ауту не менее 4MSL (8 минут). В таких случаях серверу следует передавать клиенту пакет DCCP-Reset с Reset Code 2, Aborted для сброса состояния клиента.

8.1.4. Опция Init Cookie

   +--------+--------+--------+--------+--------+--------
   |00100100| Length |         Init Cookie Value   ...
   +--------+--------+--------+--------+--------+--------
    Type=36

Опция Init Cookie позволяет серверу DCCP предотвратить смену состояния до завершения процесса трехэтапного согласования, подобно TCP SYN cookies [SYNCOOKIES]. Сервер помещает Service Code, номер своего порта и все опции, полученные в пакетах DCCP-Request и DCCP-Response в специальную переменную cookie. Обычно значение cookie шифруется с использованием ключа, известного только серверу, и включает криптографическую контрольную сумму или «магическое значение», которые позволяют проверить корректность дешифровки. Когда сервер получает назад значение cookie в отклике от клиента, он может дешифровать это значение и установить нужное состояние. До этого сервер может сохранять состояние LISTEN.

Опцию Init Cookie недопустимо передавать в пакетах DCCP-Request или DCCP-Data. Любые опции Init Cookie, полученные в пакетах DCCP-Request и DCCP-Data packets или после организации соединения (состояние соединения >= OPEN), должны игнорироваться. Сервер может включить опции Init Cookie в свой пакет DCCP-Response. В этом случае клиент должен возвращать такие же опции Init Cookie с соблюдением их порядка во всех последующих пакетах DCCP, пока один из таких пакетов не будет подтвержден (завершение трехэтапного согласования) или соединение не будет разорвано. В результате этого для клиента недопустимо использование пакетов DCCP-Data до завершения процедуры трехэтапного согласования или сброса соединения. Опции Init Cookie в пакете от клиента должны в точности соответствовать опциям, полученным в пакете DCCP-Request, указанном значением Acknowledgement Number в пакете клиента. Серверу следует использовать для Init Cookie такой формат, который допускает проверку на предмет подделки. Серверу следует отвечать на поддельные опции Init Cookie сбросом соединения с Reset Code 10, Bad Init Cookie.

В спецификации протокола не требуется точное описание реализации Init Cookie, поскольку значение Init Cookie непонятно клиенту и проблем интероперабельности возникнуть не может. В качестве примера может служить шифрование (с использованием закрытого ключа) порядковых номеров и номеров подтверждений, значения Service Code, номеров портов, всех опций из пакета DCCP-Request и соответствующего ему пакета DCCP-Response, случайного значения salt и «магического значения». При получении возвращенного клиентом значения Init Cookie сервер будет дешифровать его, проверять корректность с использованием «магического значения», порядковых номеров и номеров портов. Если полученное значение корректно, сервер будет открывать соответствующий сокет с использованием опций.

Каждая отдельная опция Init Cookie может включать до 253 байтов данных и сервер может включать в пакет более одной опции Init Cookie для увеличения объема информации.

8.1.5. Завершение согласования

Получив от сервера пакет DCCP-Response, клиент переходит из состояния REQUEST в состояние PARTOPEN и завершает процедуру трехэтапного согласования, передавая серверу пакет DCCP-Ack. Клиент остается в состоянии PARTOPEN до тех пор, пока он не обретет уверенность в том, что сервер получил тот или иной пакет, переданный клиентом из состояния PARTOPEN (начальный пакет DCCP-Ack или следующие за ним пакеты). Клиенты, желающие передавать данные из состояния PARTOPEN, должны делать это с помощью пакетов DCCP-DataAck, а не DCCP-Data. Это связано с тем, что пакеты DCCP-Data не включают номера подтверждения, поэтому сервер не может понять из пакета DCCP-Data, получил ли клиент его отклик DCCP-Response. Более того, если пакет DCCP-Response включает опцию Init Cookie, значение Init Cookie должно включаться во все пакеты, передаваемые из состояния PARTOPEN.

Один пакет DCCP-Ack, переданный при переходе в состояние PARTOPEN, может, естественно, быть потерян в сети. Клиенту следует обеспечить проверку доставки таких пакетов. Предпочтительным механизмом является использование таймера (приблизительно на 200 мсек), запускаемого при передаче каждого пакета из состояния PARTOPEN. Если отсчет для таймера закончен, а клиент сохраняет состояние PARTOPEN, ему следует генерировать новый пакет DCCP-Ack и и заново запустить таймер. Если состояние PARTOPEN сохраняется дольше 4MSL (8 минут), следует сбросить соединение с Reset Code 2, Aborted.

Клиент переходит из состояния PARTOPEN в состояние OPEN при получении от сервера корректного пакета, отличного от DCCP-Response, DCCP-Reset или DCCP-Sync.

8.2. Передача данных

В основной части соединения, связанной с обменом данными, клиент и сервер находятся в состоянии OPEN.

DCCP A передает пакеты DCCP-Data и DCCP-DataAck точке DCCP B в результате событий прикладного уровня на хосте A. Для этих пакетов используется контроль насыщения с помощью механизма CCID для полусоединения от A к B. Для пакетов же DCCP-Ack, передаваемых DCCP A, контроль насыщения осуществляется механизмом CCID для полусоединения от B к A. В общем случае DCCP A будет добавлять подтверждающую информацию в пакеты DCCP-Data, когда это возможно, создавая пакеты DCCP-DataAck. Пакеты DCCP-Ack используются в тех случаях, когда нет данных для передачи от DCCP A к DCCP B или состояние насыщения для CCID от A к B не позволяет передавать данные.

Пакеты DCCP-Sync и DCCP-SyncAck также могут использоваться в фазе обмена данными. Некоторые ситуации, вынуждающие генерировать пакеты DCCP-Sync, описаны в параграфе 7.5. Важным отличием пакетов DCCP-Sync от остальных типов пакетов является то, что получение DCCP-Sync вызывает немедленную отправку подтверждения. При получении корректного пакета DCCP-Sync конечная точка DCCP должна незамедлительно сгенерировать и передать отклик DCCP-SyncAck (подчиняясь всем ограничениям скорости передачи). Поле Acknowledgement Number пакета DCCP-SyncAck должно совпадать со значением поля Sequence Number в принятом пакете DCCP-Sync.

Отдельные реализации DCCP могут инициировать согласование признаков только после перехода в состояние OPEN. В этих случаях передача данных может оказаться недопустимой в течение некоторого времени. Данные, полученные в этот период, следует отбрасывать и уведомлять об этом с помощью опции Data Dropped Drop Block с Drop Code 0, Protocol Constraints (см. параграф 11.7).

8.3. Разрыв соединения

При разрыве соединений DCCP используется согласование, включающее необязательный пакет DCCP-CloseReq, а также пакеты DCCP-Close и DCCP-Reset. Сервер переходит из состояния OPEN (возможно, через промежуточное состояние CLOSEREQ) в состояние CLOSED; клиент переходит из состояния OPEN в состояние CLOSING, затем в состояние TIMEWAIT и, по истечении периода ожидания 2MSL (4 минуты), в состояние CLOSED.

Последовательность пакетов DCCP-CloseReq, DCCP-Close, DCCP-Reset используется в тех случаях, когда сервер хочет закрыть соединение, не удерживая себя в состоянии TIMEWAIT:

  Состояние клиента                           Состояние сервера
     OPEN                                     OPEN
1.             <--       CloseReq       <--   CLOSEREQ
2.   CLOSING   -->        Close         -->
3.             <--        Reset         <--   CLOSED (LISTEN)
4.   TIMEWAIT
5.   CLOSED

Более короткая последовательность используется для разрыва соединения по инициативе клиента.

  Состояние клиента                           Состояние сервера
     OPEN                                     OPEN
1.   CLOSING   -->        Close         -->
2.             <--        Reset         <--   CLOSED (LISTEN)
3.   TIMEWAIT
4.   CLOSED

Если сервер решить сохранить у себя состояние TIMEWAIT, используется последовательность:

Состояние клиента Состояние сервера

  Состояние клиента                           Состояние сервера
     OPEN                                     OPEN
1.             <--        Close         <--   CLOSING
2.   CLOSED    -->        Reset         -->
3.                                            TIMEWAIT
4.                                            CLOSED (LISTEN)

Во всех случаях получатель пакета DCCP-Reset удерживает соединение в состоянии TIMEWAIT. Как и в TCP, состояние TIMEWAIT сохраняется конечной точкой в течение 2MSL (4 минуты), после чего соединение закрывается. Период ожидания гарантирует, что не будет организовано новое соединение с такими же адресами и номерами портов, пока в сети могут оставаться пакеты разорванного соединения.

Далее описывается процедура согласования при разрыве соединения. Получатель корректного пакета DCCP-CloseReq должен ответить на него пакетом DCCP-Close. Получатель корректного пакета DCCP-Close должен передать в ответ пакет DCCP-Reset с Reset Code 1, Closed. Получатель корректного пакета DCCP-Reset, который одновременно является отправителем пакета DCCP-Close (и, возможно, получателем пакета DCCP-CloseReq), будет сохранять состояние TIMEWAIT для закрываемого соединения.

Пакет DCCP-Reset завершает каждое соединение DCCP, независимо от того, является закрытие соединения нормальным (по запросу приложения с Reset Code 1, Closed) или аварийным. В отличие от протокола TCP, использующего два разных механизма разрыва соединений (FIN и RST), DCCP одинаково закрывает соединения во всех случаях. Это сделано по той причине, что некоторые аспекты разрыва соединения совершенно не зависят от того, каким способом (нормально или аварийно) завершилось соединение. Например, конечной точке, получившей корректный пакет DCCP-Reset, следует сохранить для соединения состояние TIMEWAIT. Процессоры, которые должны отличать нормальное закрытие соединения от аварийного, могут проверить значение Reset Code. Реализации DCCP обычно переходят в состояние CLOSED после передачи пакета DCCP-Reset.

Конечные точки, находящиеся в состояниях CLOSEREQ и CLOSING, должны повторять передачу пакетов DCCP-CloseReq и DCCP-Close, соответственно, пока не выйдут из этого состояния. Для таймера повтора передачи следует устанавливать начальное значение так, чтобы выйти за 2 периода кругового обхода и повторять передачу не реже одного раза в течение 64 секунд, если не получен требуемый отклик.

Передавать пакеты DCCP-CloseReq и переходить в состояние CLOSEREQ разрешается только серверу. При получении пакета DCCP-CloseReq сервер должен ответить пакетом DCCP-Sync или игнорировать пакет DCCP-CloseReq.

Пакеты DCCP-Data, DCCP-DataAck и DCCP-Ack, полученные в состоянии CLOSEREQ или CLOSING можно обрабатывать или игнорировать.

8.3.1. Аварийное завершение

Конечные точки DCCP генерируют пакеты DCCP-Reset для аварийного разрыва соединения; генерация пакетов DCCP-Reset возможна из любого состояния. Пакеты сброса, переданные из состояния CLOSED, LISTEN или TIMEWAIT, используют Reset Code 3, No Connection, если явно не указано иное. Пакеты сброса, переданные из состояния REQUEST или RESPOND, используют Reset Code 4, Packet Error, если явно не указано иное.

Конечным точкам DCCP, находящимся в состоянии CLOSED, LISTEN или TIMEWAIT, может потребоваться генерация пакета DCCP-Reset в ответ на полученный от партнера пакет. Поскольку для этих состояний нет соответствующих переменных с порядковыми номерами, порядковый номер и номер подтверждения для пакета DCCP-Reset (R) берутся из полученного пакета P, как показано ниже.

  1. Если существует P.ackno, устанавливается R.seqno := P.ackno + 1. Иначе R.seqno := 0.
  2. Устанавливается R.ackno := P.seqno.
  3. Если пакет использует короткий порядковый номер (P.X == 0), для старших 24 битов R.seqno и R.ackno устанавливается значение 0.

8.4. Диаграмма состояний DCCP

Большинство смен состояний, описанных выше, можно показать на диаграм-ме состояний. Рисунок является лишь иллюстрацией, а в качестве определений следует использовать текст, приведенный в параграфе 8.5 и других местах спецификации. Например, имеются не показанные на рисунке переходы из всех состояний кроме CLOSED в состояние TIMEWAIT, связанные с полу-чением корректного пакета DCCP-Reset.

+---------------------------+    +---------------------------+
|                           v    v                           |
|                        +----------+                        |
|          +-------------+  CLOSED  +------------+           |
|          | passive     +----------+  active    |           |
|          |  open                      open     |           |
|          |                         snd Request |           |
|          v                                     v           |
|     +----------+                          +----------+     |
|     |  LISTEN  |                          | REQUEST  |     |
|     +----+-----+                          +----+-----+     |
|          | rcv Request            rcv Response |           |
|          | snd Response             snd Ack    |           |
|          v                                     v           |
|     +----------+                          +----------+     |
|     | RESPOND  |                          | PARTOPEN |     |
|     +----+-----+                          +----+-----+     |
|          | rcv Ack/DataAck         rcv packet  |           |
|          |                                     |           |
|          |             +----------+            |           |
|          +------------>|   OPEN   |<-----------+           |
|                        +--+-+--+--+                        |
|       server active close | |  |   active close            |
|           snd CloseReq    | |  | or rcv CloseReq           |
|                           | |  |    snd Close              |
|                           | |  |                           |
|     +----------+          | |  |          +----------+     |
|     | CLOSEREQ |<---------+ |  +--------->| CLOSING  |     |
|     +----+-----+            |             +----+-----+     |
|          | rcv Close        |        rcv Reset |           |
|          | snd Reset        |                  |           |
|<---------+                  |                  v           |
|                             |             +----+-----+     |
|                   rcv Close |             | TIMEWAIT |     |
|                   snd Reset |             +----+-----+     |
+-----------------------------+                  |           |
                                                 +-----------+
                              завершен отсчет для таймера 2MSL

8.5. Псевдокод

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

Принятый пакет обозначается P, сокет – S. Переменными сокета являются:

S.SWL – нижний предел окна порядковых номеров;

S.SWH – верхний предел окна порядковых номеров;

S.AWL – нижний предел окна номеров подтверждений;

S.AWH – верхний предел окна номеров подтверждений;

S.ISS -– начальный порядковый номер в переданном пакете;

S.ISR – начальный порядковый номер в принятом пакете;

S.OSR – порядковый номер в первом пакете, принятом в состоянии OPEN;

S.GSS – максимальный порядковый номер в переданных пакетах;

S.GSR – максимальный порядковый номер в принятых пакетах;

S.GAR – максимальный корректный номер подтверждения, принятый в пакетах, отличных от Sync; инициализируется значение S.ISS

Операция Send packet (передача пакета) всегда использует значение S.GSS и увеличивает его на 1.

Этап 1: Базовая проверка заголовка

      /* Этот этап проверяет корректность формата пакетов. Не прошедшие проверку пакеты 
         игнорируются без передачи в ответ пакетов Reset */
      Если пакет короче 12 байтов, он отбрасывается с возвратом управления.
      Если тип P.type непонятен, пакет отбрасывается с возвратом управления.
      Если P.Data Offset меньше размера фиксированного заголовка для данного типа пакетов или 
            больше размера пакета, пакет отбрасывается с возвратом управления.
      Если P.type не является Data, Ack или DataAck и P.X == 0 (пакет имеет короткий
             порядковый номер), пакет отбрасывается с возвратом управления.
      Если контрольная сумма заголовка некорректна, пакет отбрасывают с возвратом управления.
      Если значение P.CsCov слишком велико для размера пакета, 
             пакет отбрасывается с возвратом управления.

Этап 2: Проверка номеров портов и обработка состояния TIMEWAIT

      /* Flow ID представляет собой квартет <src addr, src port, dst addr, dst port> */
      Ищем flow ID в таблице и определяем соответствующий сокет.
      Если сокета нет или S.state == TIMEWAIT,
      /* Порядковый номер и номер подтверждения берутся из полученного пакета; см. 8.3.1. */
         Генерируется пакет Reset(No Connection), пока не будет P.type == Reset
         Отбросить пакет с возвратом управления.

Этап 3: Обработка состояния LISTEN

      Если S.state == LISTEN,
         Если P.type == Request или P содержит корректную опцию Init Cookie,
            /* Требуется просмотр опций пакета для проверки Init Cookie. Однако на этом этапе
            обрабатываются только опции Init Cookie, а остальные опции – на этапе 8. 
               Данное сканирование нужно выполнять только при наличии опций Init Cookie */
            /* Создать новый сокет и переключиться на него */
            Установить S := новый сокет для данной пары портов
            S.state = RESPOND
            Выбрать S.ISS (начальный порядковый номер) или установить из опций Init Cookie
            Инициализировать S.GAR := S.ISS
            Установить S.ISR, S.GSR, S.SWL, S.SWH из пакета или опций Init Cookie
            Продолжить с S.state == RESPOND
            /* Пакет Response будет генерироваться на этапе 11 */
         Иначе,
            Генерировать Reset(No Connection), пока не будет P.type == Reset
            Отбросить пакет с возвратом управления.

Этап 4: Подготовка порядковых номеров в состоянии REQUEST

      Если S.state == REQUEST,
         Если (P.type == Response или P.type == Reset) и S.AWL <= P.ackno <= S.AWH,
            /* установить переменные нумерации, соответствующие другой точке, чтобы  пакет P
               прошел проверки на этапе 6 */
            Установить S.GSR, S.ISR, S.SWL, S.SWH
            /* Обработка Response продолжается на этапе 10; Reset – на этапе 9 */
         Иначе,
            /* Только пакеты Response и Reset корректны в состоянии REQUEST */
            Генерировать Reset(Packet Error)
            Отбросить пакет с возвратом управления.

Этап 5: Подготовка порядковых номеров для Sync

      Если P.type == Sync или P.type == SyncAck,
         Если S.AWL <= P.ackno <= S.AWH и P.seqno >= S.SWL,
            /* P является корректным, поэтому переменные нумерации соответственно обновляются.
               После этого P передается для проверки этапа 6. При необходимости на этапе 15
               генерируется SyncAck */
            Обновить S.GSR, S.SWL, S.SWH
         Иначе,
            Отбросить пакет с возвратом управления.

Этап 6: Проверка порядковых номеров

      Если P.X == 0 и соответствующий признак Allow Short Sequential Numbers = 0,
         /* Пакет имеет короткий порядковый номер, но такие номера не разрешены */
         Отбросить пакет с возвратом управления.
      Иначе, если P.X == 0,
         Расширить P.seqno и P.ackno до 48 битов с использованием процедуры параграфа 7.6
      Пусть LSWL = S.SWL и LAWL = S.AWL
      Если P.type == CloseReq или P.type == Close или P.type == Reset,
         LSWL := S.GSR + 1, LAWL := S.GAR
      Если LSWL <= P.seqno <= S.SWH и (P.ackno не существует или LAWL <= P.ackno <= S.AWH),
         Обновить S.GSR, S.SWL, S.SWH
         Если P.type != Sync,
            Обновить S.GAR
      Иначе,
         Если P.type == Reset,
            Передать пакет Sync, подтверждающий S.GSR
         Иначе,
            Передать пакет Sync, подтверждающий P.seqno
         Отбросить пакет с возвратом управления.

 

Этап 7: Проверка неожиданных типов пакетов

      Если (S.is_server и P.type == CloseReq)
           или (S.is_server и P.type == Response)
           или (S.is_client и P.type == Request)
           или (S.state >= OPEN и P.type == Request и P.seqno >= S.OSR)
           или (S.state >= OPEN и P.type == Response и P.seqno >= S.OSR)
           или (S.state == RESPOND and P.type == Data),
         Передать пакет Sync, подтверждающий P.seqno
         Отбросить пакет с возвратом управления.

Этап 8: Обработка опций и маркировка подтверждаемости

      /* Обработка опций не описывается здесь. Некоторые опции (такие, как Mandatory) могут
         приводить к сбросу соединения при котором этапы 9 и далее не будут выполняться */
      Пометить пакет как подтверждаемый (в терминах Ack Vector – Received или Received ECN)

Этап 9: Обработка Reset

      Если P.type == Reset,
         Сбросить соединение
         S.state := TIMEWAIT
         Установить таймер TIMEWAIT
         Отбросить пакет с возвратом управления.

Этап 10: Обработка состояния REQUEST (вторая часть)

      Если S.state == REQUEST,
        /* Если мы пришли сюда, P является корректным пакетом Response от сервера (см. этап 4)
            и следует перейти в состояние PARTOPEN. В PARTOPEN нужно передать Ack, не
            передавать пакетов данных, периодически повторять передачу Ack, всегда включая 
            все опции Init Cookie из пакета Response */
         S.state := PARTOPEN
         Установить таймер PARTOPEN
         Продолжить с S.state == PARTOPEN
         /* Этап 12 будет передавать пакет Ack, завершающий трехэтапное согласование */

Этап 11: Обработка состояния RESPOND

      Если S.state == RESPOND,
         Если P.type == Request,
            Передать Response, возможно с опциями Init Cookie
            если были переданы опции Init Cookie,
               Удалить S и возвратить управление
               /* Этап 3 будет создавать другой сокет, по завершении клиентом 3-этапного 
                  согласования */
         Иначе,
            S.OSR := P.seqno
            S.state := OPEN

Этап 12: Обработка состояния PARTOPEN

      Если S.state == PARTOPEN,
         Если P.type == Response,
            Передать Ack
         Иначе, если P.type != Sync,
            S.OSR := P.seqno
            S.state := OPEN

Этап 13: Обработка CloseReq

      Если P.type == CloseReq и S.state < CLOSEREQ,
         Генерировать Close
         S.state := CLOSING
         Установить таймер CLOSING

Этап 14: Обработка Close

      Если P.type == Close,
         Генерировать Reset(Closed)
         Разорвать соединение
         Отбросить пакет с возвратом управления.

Этап 15: Обработка Sync

      Если P.type == Sync,
         Генерировать SyncAck

Этап 16: Обработка данных

      /* В этой точке все данные приложения из P могут передаваться прикладной программе. 
         Однако приложение НЕ ДОЛЖНО получать данных более, чем из одного пакета 
         Request или Response */

9. Контрольные суммы

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

Область покрытия контрольной суммы может оказывать влияние также на работу механизма контроля насыщения. Пакет с поврежденными данными приложения, которые были учтены в контрольной сумме, трактуются как потерянные. Это может приводить к жесткой реакции на потери со стороны механизма контроля насыщения отправителя, который может в результате необоснованно применять санкции к соединениям через каналы с высоким фоновым уровнем ошибок. Комбинация уменьшенного покрытия для контрольной суммы заголовка и опций Data Checksum может приводить к тому, что конечные точки будут сообщать о поврежденных пакетах, не отбрасывая их, и будут использовать для уведомления опции Data Dropped и Drop Code 3 (см. параграф 11.7). Такой подход может давать приложениям некоторые преимущества. Однако нужны дополнительные исследования для определения подходящего отклика на повреждение данных, которое может в некоторых случаях напоминать насыщение. В настоящее время отклик на поврежденные пакеты происходит так же, как отклик на потерю пакетов.

Опция Data Checksum, которая использует сильный алгоритм CRC, позволяет конечным точкам детектировать повреждение данных приложения. В этом случае можно использовать API для предотвращения доставки приложению поврежденных пакетов даже в тех случаях, когда конечная точка получает из канала поврежденные данные при использовании уменьшенного покрытия для контрольной суммы заголовка. Однако снижение покрытия контрольной суммы заголовка для приложений, которым требуются корректные данные, в настоящее время рассматривается как экспериментальное. Это связано с тем, что сумма потерь и повреждений для пакетов с неполным покрытием контрольной суммы может быть существенно выше, нежели для пакетов, в которых контрольная сумма учитывает все данные, хотя доля потерянных пакетов в общем случае будет ниже. Реальное поведение будет зависеть от канала и для окончательного выбора требуется дополнительный опыт и исследования.

Снижение области покрытия контрольной суммой создает некоторые проблемы безопасности, рассмотренные в параграфе 18.1. Приложение B содержит дополнительную информацию по вопросу выбора области покрытия контрольной суммы. Реализации DCCP с неполным покрытием для контрольной суммы берут свое начало от UDP-Lite [RFC3828].

9.1. Поле Checksum в заголовке

DCCP использует алгоритм расчета контрольных сумм TCP/IP. Поле Checksum в базовом заголовке DCCP (см. параграф 5.1) представляет собой 16-битовое дополнение до 1 суммы 16-битовых дополнений до 1 всех 16-битовых слов заголовка DCCP, опция DCCP, псевдозаголовка, взятого из заголовка сетевого уровня и, в зависимости от значения поля Checksum Coverage, части или всех данных приложения. При расчете контрольной суммы значение поля Checksum принимается нулевым. Если пакет содержит нечетное количество байтов в полях, используемых для расчета контрольной суммы, справа к последнему байту добавляется 8 нулевых битов для формирования полного 16-битового слова при вычислении контрольной суммы. Этот байт заполнения не передается через сеть.

Псевдозаголовок вычисляется так же, как для протокола TCP. Для IPv4 он имеет размер 96 битов и включает адреса IPv4 для получателя и отправителя, номер протокола IP для DCCP (дополняется слева 8 битами с нулевым значением) и размер DCCP в 16-битовых словах (длина заголовка DCCP вместе с опциями плюс размер всех данных), как описано в параграфе 3.1 [RFC793]. Для IPv6 псевдозаголовок имеет размер 320 и включает адреса IPv6 для отправителя и получателя, размер DCCP в 32-битовых словах, номер протокола IP для DCCP (дополняется слева 24 битами с нулевым значением), как описано в параграфе 8.1 [RFC2460].

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

9.2. Поле заголовка Checksum Coverage

Поле Checksum Coverage в базовом заголовке DCCP (см. параграф 5.1) задает, какая часть пакета учитывается при вычислении контрольной суммы в поле Checksum:

CsCov = 0

Поле Checksum учитывает заголовок DCCP, опции DCCP, псевдозаголовок сетевого уровня и все данные приложения в пакете, возможно дополненные справа нулями для выравнивания по границе 16-битового слова.

CsCov = 1-15

Поле Checksum учитывает заголовок DCCP, опции DCCP, псевдозаголовок сетевого уровня и начальные (CsCov-1)*4 байтов данных приложения.

Таким образом, при CsCov = 1 данные приложения в контрольной сумме не учитываются совсем. Значение (CsCov-1)*4 должно быть не более общего размера данных приложения в пакете. Пакеты с некорректными значениями CsCov должны игнорироваться. В частности, недопустима обработка опций из таких пакетов. Толкование значений поля, отличных от 0 и 1, следует считать экспериментальным.

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

Прикладному интерфейсу DCCP следует позволять передающим приложениям предлагать значение CsCov для передаваемых пакетов, используя по умолчанию 0 (полное покрытие). Признак Minimum Checksum Coverage, описанный ниже, позволяет конечной точке отвергнуть доставку данных в пакетах с частичным покрытием для контрольной суммы – по умолчанию принимаются данные приложения только с полным покрытием. Нижележащие уровни, которые поддерживают частичное детектирование ошибок, могут использовать поле Checksum Coverage как рекомендацию, где не требуется искать возможные ошибки. Нижележащие уровни должны использовать строгий механизм детектирования для обнаружения ошибок по крайней мере в важных частях пакета и отбрасывания поврежденных пакетов. К важным частям относятся байты, расположенные между первым байтом заголовка IP и последним байтом, указанным полем Checksum Coverage.

Более детальное обсуждение вопросов частичного покрытия для контрольной суммы в части прикладного уровня и интерфейса с нижележащим уровнем приводится в [RFC3828].

9.2.1. Признак Minimum Checksum Coverage

Признак Minimum Checksum Coverage позволяет конечной точке DCCP определить будет ли партнер принимать пакеты со сниженным значением Checksum Coverage. Например, DCCP A передает опцию Change R(Minimum ChecksumCoverage, 1) точке DCCP B, чтобы проверить будет ли B принимать пакеты с Checksum Coverage = 1.

Признак Minimum Checksum Coverage имеет номер 8 и устанавливается с приоритетом сервера. Признак принимает однобайтовые целочисленные значения от 0 до 15; значения от 16 и выше зарезервированы. Признак Minimum Checksum Coverage/B отражает значения Checksum Coverage, которые DCCP B считает неприемлемыми. Пусть Minimum Checksum Coverage/B = MinCsCov. Тогда

  • если MinCsCov = 0, DCCP B будет принимать только пакеты с CsCov = 0;
  • если MinCsCov > 0, DCCP B будет также принимать пакеты с CsCov >= MinCsCov.

DCCP B может отказаться от обработки данных приложения из пакетов с недопустимым значением Checksum Coverage. О таких пакетах следует сообщать с помощью опций Data Dropped (параграф 11.7) с Drop Code 0, Protocol Constraints. Новые соединения начинаются с Minimum Checksum Coverage = 0 для обеих сторон.

9.3. Опция Data Checksum

Опция Data Checksum содержит 32-битовую контрольную сумму CRC-32c для данных приложения в пакете DCCP.

   +--------+--------+--------+--------+--------+--------+
   |00101100|00000110|              CRC-32c              |
   +--------+--------+--------+--------+--------+--------+
    Type=44  Length=6

Передающая точка DCCP рассчитывает значение CRC для байтов, содержащихся в области данных приложения, и помещает полученное значение в поле данных опции. Для расчета значения опции Data Checksum используется такой же алгоритм CRC-32c, который применяется в SCTP [RFC3309]. Отметим, что значение контрольной суммы CRC-32c для 0 байтов данных равно 0. Контрольная сумма заголовка DCCP будет учитывать значение опции Data Checksum, поэтому контрольную сумму данных требуется вычислять заранее, до расчета контрольной суммы заголовка.

Конечная точка DCCP, получившая пакет с опцией Data Checksum, должна или может проверить контрольную сумму данных приложения – выбор определяется значением признака Check Data Checksum, описанного ниже. При проверке контрольной суммы последняя рассчитывается с использованием того же алгоритма CRC-32c, который применялся для расчета значения поля Data Checksum. Если значение рассчитанной контрольной суммы не совпадает с полученным, конечная точка может реагировать одним из двух способов, описанных ниже.

  • Принимающее приложение может принимать заведомо поврежденные данные через некий специальный дополнительный интерфейс API. В этом случае данные из пакета должны передаваться приложению вместе с информацией о повреждении данных. Более того, принимающая конечная точка должна сообщить о доставке поврежденного пакета на передающую сторону с помощью опции Data Dropped (Drop Code 7, Delivered Corrupt).
  • В остальных случаях принимающая конечная точка должна отбросить данные приложения и сообщить о повреждении на передающую сторону с помощью опции Data Dropped (Drop Code 3, Corrupt).

В обоих случаях пакет считается подтверждаемым (поскольку обработка заголовка была проведена) и, следовательно, будет подтверждаться с использованием эквивалента Ack Vector для состояния Received или Received ECN Marked.

Хотя опция Data Checksum предназначена для пакетов, содержащих данные приложения, ее можно включать и в другие пакеты (такие, как DCCP-Ack, DCCP-Sync и DCCP-SyncAck). Получателю следует рассчитывать для области данных таких пакетов контрольную сумму CRC-32c, как это делается для пакетов DCCP-Data и других пакетов с данными приложения. Если значения CRC не совпадают, об это требуется сообщить с использованием опции Data Dropped (Drop Code 3), хотя данные в любом случае не доставляются приложению.

9.3.1. Признак Check Data Checksum

Признак Check Data Checksum позволяет конечной точке DCCP определить будет ли ее партнер проверять опции Data Checksum. Точка DCCP A передает обязательную (Mandatory) опцию Change R(Check Data Checksum, 1) точке DCCP B, чтобы потребовать от той проверки опций Data Checksum (в противном случае соединение будет сбрасываться).

Признак Check Data Checksum имеет номер 9 и устанавливается с приоритетом сервера. Этот признак принимает однобайтовые логические значения. Конечная точка DCCP B должна проверять все полученные опции Data Checksum, если Check Data Checksum/B = 1, хотя она может проверять эти опции и в случае Check Data Checksum/B = 0. Значения 2 и больше для этого признака являются резервными. Новые соединения организуются с Check Data Checksum = 0 для обеих сторон.

9.3.2. Использование контрольных сумм

Каналы Internet обычно достаточно строго проверяют целостность передаваемых пакетов [RFC3828, RFC3819]. По умолчанию заголовок DCCP содержит Checksum Coverage = 0 (полное покрытие). Однако значение Checksum Coverage может быть и отличным от нуля. Задавая частичное покрытие для контрольной суммы заголовка, приложение показывает свою устойчивость к повреждению данных, не защищенных контрольной суммой. Понимая это, канальный уровень может снизить строгость детектирования и/или корректировки ошибок при передаче незащищенных частей. В результате это приведет к существенному росту вероятности повреждения данных при передаче. Опция Data Checksum позволяет с очень высокой вероятностью детектировать такие повреждения.

10. Контроль насыщения

Каждый механизм контроля насыщения, поддерживаемый протоколом DCCP, имеет идентификатор CCID, который представляет собой целое число от 0 до 255. При организации соединения (а в некоторых случаях и в процессе работы соединения) конечные точки выбирают механизм контроля насыщения путем согласования значений признаков CCID. Признак CCID имеет номер 1. Значение CCID/A равно идентификатору CCID, используемому для полусоединения от A к B. DCCP B передает опцию Change R(CCID, K) для того, чтобы запросить у DCCP A использование CCID K для своих пакетов данных. Признак устанавливается с приоритетом сервера, поэтому опции согласования CCID могут содержать множество подходящих значения CCID, отсортированных в порядке предпочтения. Например, опция Change R(CCID, 2 3 4) запрашивает у получателя использование CCID 2 для своих пакетов и показывает, что подходят также CCID 3 и CCID 4 (это соответствует последовательности байтов 35, 6, 1, 2, 3, 4: опция Change R (35), размер опции (6), идентификатор признака (1), значения CCID (2, 3, 4)). Аналогично, опция Confirm L(CCID, 2, 2 3 4) говорит ее получателю, что отправитель использует для своих пакетов CCID 2, но приемлемы также значения CCID 3 и CCID 4.

Определенные в настоящее время значения CCID перечислены в таблице 5.

Таблица 5: Идентификаторы механизмов контроля насыщения DCCP

CCID Название Документ

0-1

Резерв

[RFC4341]

2

TCP-like Congestion Control

[RFC4342]

3

TCP-Friendly Rate Control

4 – 255

Резерв

Новые соединения начинаются с использования обеими точками CCID 2. Если такой выбор неприемлем для конечной точки DCCP, она должна передать с флагом Mandatory опцию Change(CCID) в своих первых пакетах.

Все CCID, стандартизованные для использования с DCCP, будут соответствовать механизмам контроля насыщения, предварительно стандартизованным IETF. Мы предполагаем, что в течение некоторого времени все такие механизмы будут дружественны к TCP, но это не является требованием DCCP.

Реализациям DCCP, предназначенным для решения задач общего назначения, таким, как реализации протокола в ядрах операционных систем общего назначения, следует поддерживать по крайней мере CCID 2. Широкое распространение CCID 2 обеспечит интероперабельность, хотя отдельные приложения могут запрещать использование этого механизма.

10.1. Контроль насыщения в стиле TCP

CCID 2 (TCP-like Congestion Control – контроль насыщения в стиле TCP) обозначает механизм контроля насыщения с аддитивным увеличением AI и мультипликативным уменьшением MD (AIMD3), в соответствии с моделью, используемой для протокола TCP, включая окно насыщения, замедленный старт, таймауты и т. п. [RFC2581]. Механизм CCID 2 обеспечивает максимальное использование полосы в течение продолжительного периода, совместимое со сквозным контролем насыщения, но уменьшает вдвое окно насыщения в ответ на каждый факт возникновения перегрузки. Это ведет к внезапным изменениям скорости, характерным для TCP. Приложениям следует использовать CCID 2, если они предпочитают использовать максимально доступную полосу для установившейся скорости. Это зачастую относится к приложениям, которые не доставляют данные непосредственно пользователю.

Например, гипотетическое приложение для передачи файлов на основе DCCP, использующее управление повторной передачей на прикладном уровне в случаях потери пакетов, может предпочесть CCID 2 по сравнению с CCID 3. Для интерактивных сетевых игр также может оказаться предпочтительным использование CCID 2.

Подробное описание CCID 2 содержится в [RFC4341].

10.2. Контроль насыщения TFRC

CCID 3 обозначает механизм контроля насыщения TFRC4, основанный на выравнивании. Механизм TFRC разработан для обеспечения разумно беспристрастного распределения полосы между одновременными потоками в стиле TCP. Разумная беспристрастность означает, что скорость потока не более, чем вдвое отличается от скорости потока TCP при таких же условиях. Однако для TFRC характерны существенно более низкие вариации изменения пропускной способности во времени по сравнению с TCP и это делает механизм CCID 3 более предпочтительным по сравнению с CCID 2 для потоковых приложений, где важна относительно стабильная скорость передачи.

Подробное описание CCID 3 содержится в [RFC4342]. Механизм контроля насыщения TFRC изначально был описан в [RFC3448].

10.3. Опции, признаки и коды сброса, связанные с CCID

Половина значений типов опций, номеров признаков и Reset Code зарезервирована для использования с конкретными CCID. Механизмам CCID могут потребоваться новые опции (например, для обмена информацией о подтверждениях или скорости); например, резервирование пространства опций позволяет механизмам CCID создавать опции без изменения в пространстве глобальных опций протокола. Например, опция 128 может иметь разное значение для полусоединения с CCID 4 и полусоединения с CCID 8. Специфические для CCID опции и признаки никогда не будут конфликтовать с глобальными опциями и признаками, которые могут появиться в новых версиях данной спецификации.

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

  • Опции с номерами от 128 до 191 относятся к числу опций, передаваемых от отправителя (HC-Sender) к получателю (HC-Receiver) в данном полусоединении, а опции с номерами от 192 до 255 передаются от получателя к отправителю.
  • Значения Reset Code от 128 до 191 показывают, что отправитель (HC-Sender) сбросил соединение (скорей всего в результате проблем с подтверждениями, переданными HC-Receiver). Значения Reset Code от 192 до 255 показывают, что получатель (HC-Receiver) сбросил соединение (скорей всего в результате проблем с пакетами данных, переданными HC-Sender).
  • Номера от 128 до 191 используются для признаков, поддерживаемых на стороне отправителя (HC-Sender); номера от 192 до 255 – для признаков, поддерживаемых на стороне получателя (HC-Receiver). Поскольку опции Change L и Confirm L для признаков передаются той стороной, на которой реализован признак, ясно, что любая опция Change L(128) передается со стороны HC-Sender, а любая опция Change L(192) – со стороны HC-Receiver. Аналогично, опция Change R(128) передается со стороны HC-Receiver, а опция Change R(192) – со стороны HC-Sender.

В качестве примера рассмотрим соединение DCCP, где полусоединение от A к B использует CCID 4, а полусоединение от B к A – CCID 5. На рисунке показана выборка связанных с CCID опций для обоих полусоединений.

Пакет   Опция               Полусоед.  CCID
------  ------              ---------  ----
A > B   128                  от A к B   4
A > B   192                  от B к A   5
A > B   Change L(128, ...)   от A к B   4
A > B   Change R(192, ...)   от A к B   4
A > B   Confirm L(128, ...)  от A к B   4
A > B   Confirm R(192, ...)  от A к B   4
A > B   Change R(128, ...)   от B к A   5
A > B   Change L(192, ...)   от B к A   5
A > B   Confirm R(128, ...)  от B к A   5
A > B   Confirm L(192, ...)  от B к A   5
B > A   128                  от B к A   5
B > A   192                  от A к B   4
B > A   Change L(128, ...)   от B к A   5
B > A   Change R(192, ...)   от B к A   5
B > A   Confirm L(128, ...)  от B к A   5
B > A   Confirm R(192, ...)  от B к A   5
B > A   Change R(128, ...)   от A к B   4
B > A   Change L(192, ...)   от A к B   4
B > A   Confirm R(128, ...)  от A к B   4
B > A   Confirm L(192, ...)  от A к B   4

Использование связанных с CCID опций и признаков в процессе согласования не рекомендуется, поскольку в момент обработки таких опций сложно предсказать, какое значение CCID будет выбрано. Например, если пакет DCCP-Request содержит последовательность опций Change L(CCID, 3), 128, связанная с CCID опция 128 может обрабатываться CCID 3 (если сервер поддерживает CCID 3) или принятым по умолчанию CCID 2 (если сервер не поддерживает CCID 3). Однако можно безопасно включать связанные с CCID опции совместно с опцией Mandatory. Например, если пакет DCCP содержит последовательность опций Mandatory, Change L(CCID, 3), 128, тогда опция 128 будет обработана CCID 3 или соединение просто будет сброшено.

Серверы, которые не поддерживают принятый по умолчанию механизм CCID 2, могут никогда не получать связанных с CCID 2 опций в пакетах DCCP-Request (поскольку сервер должен передавать опции Mandatory Change(CCID) в своем пакете DCCP-Response, связанные с CCID опции во всех остальных пакетах не будут относиться к CCID 2). Сервер должен трактовать такие опции как непонятные. Таким образом, он будет сбрасывать соединение, встретив опцию Mandatory, связанную с CCID, или запрос на согласование признака передавая пустую опцию Confirm для необязательной опции Change по изменению связанного с CCID признака и игнорируя остальные связанные с CCID опции.

10.4. Требования к профилям CCID

Каждый документ CCID Profile должен удовлетворять по крайней мере перечисленным ниже требованиям:

  • Профиль должен включать имя и номер описываемого механизма CCID.
  • Профиль должен описывать условия, в которых этот механизм явно будет полезен. Зачастую лучшим способом будет являться сравнение с существующими CCID.
  • Профиль должен перечислять и описывать все связанные с данным CCID опции, признаки, значения Reset Code; следует также указать, какие из опций и признаков общего назначения, описанных в настоящем документе, имеют отношение к данному CCID.
  • Все новые механизмы подтверждения должны включать способ передачи сигналов ECN Nonce Echo отправителю.
  • Профиль должен описывать формат пакетов данных, всех опций, которые следует включать, и установку поля Ccval в заголовке.
  • Профиль должен описывать формат пакетов подтверждения, включая опции, которые следует помещать в эти пакеты.
  • Профиль должен определять контроль насыщения для пакетов данных. Это описание включает отклики на факты насыщения, простои, периоды вносимых приложением ограничений, а также опции DCCP Data Dropped и Slow Receiver. Механизмам CCID, которые реализуют контроль насыщения на уровне отдельных пакетов, следует указывать, как размер пакетов влияет на принимаемые механизмом контроля решения.
  • Профиль должен указывать, когда генерируются подтверждения и как контролируется насыщение для них.
  • Профиль должен определять, когда использующий CCID отправитель считается статичным.
  • Профиль должен указывать, нужно ли подтверждать подтверждения CCID и как часто это следует делать.

10.5. Состояние насыщения

Большинство алгоритмов контроля насыщения принимает во внимание предысторию при определении текущего значения допустимой скорости. В CCID 2 характеристики насыщения включают окно насыщения и меру числа пакетов, остающихся в сети. В CCID 3 характеристики включают продолжительность недавних интервалов потерь. Оба механизма CCID используют оценку времени кругового обхода. Характеристики насыщения зависят от пути через сеть и становятся некорректными при смене пути. Поэтому отправителям и получателям DCCP следует сбрасывать свои характеристики насыщения, заново запуская механизм контроля из состояния slow start или его эквивалента, при существенном изменении сквозного пути через сеть. Например, конечной точке, которая передает или принимает сообщение Mobile IPv6 Binding Update [RFC3775], следует сбросить свои характеристики насыщения для всех соответствующих соединений DCCP.

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

11. Подтверждения

Контроль насыщения требует от получателей передачи отправителю информации о потерянных пакетах или пакетах с метками ECN. Получатели DCCP должны сообщать о любой замеченной перегрузке, как определено в соответствующем профиле CCID. Каждый механизм CCID указывает, когда должны передаваться подтверждения, какие опции они должны использовать и т. п. Для подтверждений DCCP также используется контроль насыщения, хотя от потока подтверждений не требуется ничего сверх подобия TCP friendly; каждый CCID определяет контроль насыщения для пакетов подтверждения.

Большинство подтверждений использует опции DCCP. Например, в полусоединении с CCID 2 (TCP-like) получатель передает подтверждающую информацию с использованием опции Ack Vector. В этом параграфе описываются опции общего назначения для подтверждений и показано, как подтверждения используют эти опции в условиях общего типа. Полное описание механизмов подтверждения, используемых каждым CCID, приводится в спецификации профиля CCID.

Опции подтверждений, такие, как Ack Vector, зависят от номера подтверждения DCCP и, таким образом, могут передаваться лишь в пакетах, где может присутствовать поле Acknowledgement Number. Опции подтверждения, полученные в пакетах иного типа, а именно, DCCP-Request и DCCP-Data, должны игнорироваться. Однако не все опции подтверждения являются обязательными для каждого пакета, содержащего поле Acknowledgement Number.

11.1. Подтверждения подтверждений и односторонние соединения

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

Проблема подтверждения подтверждений возникает из-за того, что некоторые механизмы подтверждения используют гарантированную доставку. Например, получатель HC-Receiver, использующий CCID 2 (TCP-like Congestion Control), передает подтверждения Ack Vector, содержащие подтверждающую информацию, с полной гарантией доставки. Точке HC-Sender следует время от времени информировать точку HC-Receiver о получении подтверждений. Если этого не делать, HC-Receiver может повторить передачу данных Ack Vector с самого начала соединения (для каждого пакета DCCP-Ack)! Однако следует отметить, что сами по себе подтверждения подтверждений не обязательно должны доставляться с гарантией – когда подтверждения подтверждений теряются, HC-Receiver будет просто поддерживать и периодически заново передавать старые состояния, связанные с подтверждениями. Следовательно не возникает необходимости в «подтверждении подтверждения подтверждений».

При двухстороннем обмене данными все требуемые подтверждения подтверждений автоматически включаются в нормальные подтверждения доставки данных. Для односторонних соединений, однако, получатель DCCP не передает данных, поэтому отправитель обычно не шлет подтверждений. Следовательно, механизм CCID соответствующего полусоединения должен явно говорить, когда и как отправителю (HC-Sender) следует генерировать подтверждения подтверждений.

В качестве примера рассмотрим двухстороннее соединение, в котором обе половины используют один механизм CCID (2 или 3), и DCCP B перестает передавать данные, т. е., соединение становится односторонним.

DCCP B прекращает передачу данных и шлет DCCP A только пакеты DCCP-Ack. В случае CCID 2 (TCP-like Congestion Control) DCCP B использует Ack Vector для надежной доставки информации о получении пакетов. Как сказано выше, точка DCCP A должна время от времени подтверждать «чистые» подтверждения от DCCP B, чтобы точка B могла освобождать старые состояния Ack Vector. Например, A может передавать пакет DCCP-DataAck взамен DCCP-Data. Однако в случае CCID 3 состояния подтверждений в общем случае «привязаны», поэтому точке A не требуется подтверждать подтверждения от точки B.

При односторонней связи один механизм CCID (например, CCID соединения от A к B) управляет всеми подтверждениями DCCP в плане их содержимого, частоты и т. п. Для двухсторонних соединений CCID полусоединения от A к B управляет подтверждениями DCCP B (включая подтверждения подтверждений DCCP A), а CCID полусоединения от B к A управляет подтверждениями A.

DCCP A переключает свою картину подтверждений из двухсторонней в одностороннюю, когда узнает, что точка DCCP B перестала передавать данные (статична). Обратное переключение в двухсторонний режим происходит тогда, когда точка A должна подтвердить хотя бы один пакет DCCP-Data или DCCP-DataAck от точки DCCP B.

Каждый механизм CCID определяет способ детектирования статичности для этого CCID и способ организации подтверждения подтверждений для односторонних соединений. CCID полусоединения от B к A определяет, когда DCCP B становится статичным. Обычно это происходит по истечении определенного периода, в течение которого точка B не передает ни одного пакета данных; в CCID 2, например, этот период равен большему из двух значений – 0,2 и два интервала кругового обхода. CCID от A к B определяет, как DCCP A обеспечивает подтверждения подтверждений после того, как точка DCCP B становится статичной.

11.2. Добавление подтверждений

Данные подтверждения от A к B могут «прицепляться» к данным, передаваемым точкой DCCP B, если это не задерживает доставку подтверждения больше, чем дозволено CCID от A к B. Однако для данных подтверждения зачастую требуется более 4 байтов. Большой объем данных подтверждения, добавленных перед большим блоком данных может привести к тому, что размер пакета превысит максимально допустимое значение. В этом случае DCCP B следует передавать раздельные пакеты DCCP-Data и DCCP-Ack или подождать (но не слишком долго) отправки более мелкой дейтаграммы.

Использование «прицепа5» является общепринятым для DCCP A, когда полусоединение от B к A становится статичным, т. е., когда DCCP A просто подтверждает подтверждения DCCP B. Существует три причины подтверждения подтверждений DCCP B – чтобы позволить DCCP B освободить информацию о ранее подтвержденных пакетах данных от A, уменьшить размер будущих подтверждений и управлять скоростью, с которой подтверждения будут передаваться. Поскольку все эти причины являются второстепенными, DCCP A может обычно дождаться пакета данных для добавления к нему данных подтверждения. Если точка DCCP B захочет получить подтверждение раньше, она может передать пакет DCCP-Sync.

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

11.3. Признак Ack Ratio

Признак Ack Ratio позволяет отправителю (HC-Sender) влиять на скорость, с которой получатели (HC-Receiver) генерируют пакеты DCCP-Ack, влияя таким образом на загрузку обратного пути. Это отличается от протокола TCP, который в настоящее время не контролирует насыщение для трафика, содержащего «чистые» подтверждения. Контроль насыщения на пути возврата с помощью Ack Ratio не пытается быть похожим на TCP – он просто старается предотвратить возможное насыщение и обеспечить более эффективное, нежели в TCP, поведение для случаев потери или маркировки большого числа пакетов на пути возврата.

Ack Ratio применяется к CCID, чьи получатели (HC-Receiver) слишком часто подтверждают пакеты данных. Значение Ack Ratio/A равно округленному отношению числа пакетов данных, переданных DCCP A, к числу пакетов DCCP-Ack, переданных DCCP B. Более высокие значения Ack Ratio соответствуют более редкой передаче пакетов DCCP-Ack; отправитель поднимает Ack Ratio, когда путь возврата перегружается, и снижает Ack Ratio при свободном пути возврата. Каждый профиль CCID определяет способ контроля насыщения на пути подтверждений и, в частности, использование Ack Ratio. Например, CCID 2 использует Ack Ratio для контроля насыщения на пути подтверждений, CCID 3 не использует. Однако каждый признак Ack Ratio имеет определенное значение, независимо от того, используется ли это значение соответствующим CCID.

Признак Ack Ratio имеет номер 5 и устанавливается без согласования. Признак принимает двухбайтовые целочисленные значения. Значение Ack Ratio/A = 4 означает, что DCCP B будет передавать по крайней мере один пакет подтверждения на каждые 4 пакета данных, переданные DCCP A. Точка DCCP A передает опцию Change L(Ack Ratio) для того, чтобы уведомить DCCP B о допустимом числе подтверждений. Значение Ack Ratio = 0 говорит, что соответствующее полусоединение не использует Ack Ratio для контроля за частотой подтверждений. Новые соединения начинаются с Ack Ratio 2 для обеих точек; это значение обеспечивает поведение подтверждений, аналогичное отложенным подтверждениям в TCP.

Значения Ack Ratio следует трактовать, как рекомендации, а не жесткие требования. Управляемое с помощью Ack Ratio поведение системы подтверждения доставки похоже на поведение подтверждений TCP в отсутствии насыщения и несколько более консервативно при возникновении перегрузки на пути возврата. Соответствие этим задачам является более важным, нежели точная реализация Ack Ratio. В частности, следует выполнять ряд рекомендаций:

  • Получатели могут добавлять подтверждающую информацию в пакеты данных, создавая для этого пакеты DCCP-DataAck. Признак Ack Ratio не относится к подтверждениям, добавленным в пакеты данных. Однако, если пакет данных слишком велик, чтобы добавлять к нему подтверждение, или частота передачи данных ниже, чем предлагает значение Ack Ratio для подтверждений, точке DCCP B следует передавать «чистые» пакеты DCCP-Ack для обеспечения генерации одного подтверждения на Ack Ratio принятых пакетов данных.
  • Получатели могут поднять частоту передачи подтверждений вместо передачи подтверждения сразу же по получении пакета данных. Получателям, повышающим частоту передачи подтверждений, следует поднимать ее приблизительно до уровня Ack Ratio, а также следует включать опции Elapsed Time (параграф 13.2), чтобы помочь отправителю рассчитать время кругового обхода.
  • Получателям следует поддерживать таймеры отложенных подтверждений (подобно TCP), с помощью которых подтверждения пакетов могут задерживаться не более, чем на T секунд. Задержка позволяет получателю собрать дополнительные пакеты для подтверждения и снизить связанный с подтверждениями объем служебного трафика. По прошествии времени T подтверждение передается без дополнительного ожидания. По умолчанию для T следует устанавливать значение 0,2 секунды, принятое в большинстве реализаций TCP. Это может приводить к более частой передаче подтверждений, нежели задает значение Ack Ratio.
  • Получателям следует передавать подтверждения незамедлительно по получении для пакетов с маркировкой ECN Congestion Experienced и пакетов с нарушением порядка доставки, что может говорить о потере пакетов. Однако нет необходимости в передаче незамедлительных подтверждений чаще одного раза за период кругового обхода.
  • Получатели могут игнорировать значение Ack Ratio, если они осуществляют свой контроль насыщения для подтверждений. Например, получатель, который знает частоту потери и маркировки пакетов DCCP-Ack, может по своему усмотрению поддерживать частоту передачи подтверждений в стиле TCP. Такие получатели должны обеспечивать постоянное наличие информации о частоте потери и маркировки пакетов или возвращаться к использованию Ack Ratio в случаях нехватки такой информации, которая может возникать в период статичности получателя.

11.4. Опции Ack Vector

Опции Ack Vector обеспечивает групповое кодирование истории получения пакетов данных клиентом. Каждый байт вектора дает состояние пакета данных в истории потерь и число предшествующих пакетов с таким же состоянием. Вид опции показан на рисунке.

   +--------+--------+--------+--------+--------+--------
   |0010011?| Length |SSLLLLLL|SSLLLLLL|SSLLLLLL|  ...
   +--------+--------+--------+--------+--------+--------
   Type=38/39         \___________ Vector ___________...

Два варианта опции Ack Vector (тип 38 и 39) отличаются лишь значениями, которые они подразумевают для ECN Nonce Echo (см. параграф 12.2).

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

    0 1 2 3 4 5 6 7
   +-+-+-+-+-+-+-+-+
   |Sta| Run Length|
   +-+-+-+-+-+-+-+-+

Таблица 6: Состояния DCCP Ack Vector

Состояние Название

0

Received

1

Received ECN Marked

2

резерв

3

Not Yet Received

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

Термин ECN marked относится к пакетам, с кодом ECN 11, CE (Congestion Experienced); о пакетах, принятых с таким кодом ECN, должно передаваться уведомление с использованием State 1, Received ECN Marked. О пакетах, полученных с кодами ECN 00, 01 или 10 (Non-ECT, ECT(0) и ECT(1), соответственно), должно передаваться уведомление с использованием State 0, Received.

Поле Run Length (младшие шесть битов каждого байта) указывает количество последовательных пакетов в состоянии State. Значение Run Length = 0 говорит о том, что соответствующее состояние относится только к одному пакету, значение Run Length = 63 говорит, что состояние относится к 64 последовательным пакетам. При числе пакетов 65 и более должны использоваться несколько байтов.

Первый байт первой опции Ack Vector относится к пакету, указанному полем Acknowledgement Number, а следующие байты относятся к более старым пакетам. Недопустимо передавать опции Ack Vector в пакетах DCCP-Data и DCCP-Request, которые не имеют поля Acknowledgement Number, и все опции Ack Vector, полученные в таких пакетах, должны игнорироваться.

Опция Ack Vector, содержащая десятичные значения 0,192,3,64,5, для которой поле Acknowledgement Number имеет десятичное значение 100, показывает, что:

пакет 100 был получен (Acknowledgement Number 100, State 0, Run Length 0);

пакет 99 был потерян (State 3, Run Length 0);

пакеты 98, 97, 96 и 95 были получены (State 0, Run Length 3);

пакет 94 имел маркер ECN (State 1, Run Length 0);

пакеты 93, 92, 91, 90, 89, 88 были получены (State 0, Run Length 5).

Одна опция Ack Vector может подтверждать до 16192 пакетов данных. Если нужно подтвердить больше пакетов, нежели можно указать в 253 байтах опции Ack Vector, можно передать множество опций Ack Vector; вторая опция Ack Vector начинается там, где заканчивается первая и т. д..

Состояния Ack Vector подчиняются двум ограничениям общего значения (эти принципы следует использовать также для других механизмов подтверждения; состояния Ack Vector просто позволяют упростить разъяснение принципов):

  1. Пакеты, для которых указывается State 0 или State 1, должны быть подтверждаемыми – их опции должны быть обработаны принимающим стеком DCCP. Любые данные из пакетов не обязательно доставляются приложению – фактически они могут быть просто отброшены.
  2. Пакеты, для которых указывается State 3, должны быть неподтверждаемыми. Согласование признаков и опции таких пакетов недопустимо обрабатывать и таким пакетам недопустимо ставить в соответствие значение Acknowledgement Number.

О пакетах, отброшенных в приемном буфере приложения, должны передаваться уведомления, как о Received или Received ECN Marked (состояния 0 и 1), в зависимости от состояния ECN; значения ECN Nonce из таких пакетов должны включаться в Nonce Echo. Опция Data Dropped информирует отправителя о том, что некоторые пакеты, указанные, как принятые, на самом деле были отброшены на уровне приложения.

Одну или несколько опций Ack Vector, которые (совместно) сообщают о состоянии пакета с порядковым номером меньше ISN (начальный порядковый номер), следует рассматривать, как некорректные. Принимающей точке DCCP следует игнорировать такие опции или сбросить соединение с использованием Reset Code 5, Option Error. Ни одна из опций Ack Vector не может относиться к пакетам, которые еще не были переданы, что можно проверить с помощью Acknowledgement Number, как описано в параграфе 7.5.3, но в результате атак, ошибок в реализациях или некорректного поведения опция Ack Vector может показывать, что пакет был принят до его реальной доставки. В параграфе 12.2 описаны методы обнаружения таких случаев и реакция отправителя на них. Пакеты, которые не были включены ни в одну опцию Ack Vector, отправителю следует трактовать как еще не принятые (not yet received, State 3).

В Приложении A приведено не являющееся нормативным описание деталей обработки подтверждений DCCP в контексте абстрактной реализации Ack Vector.

11.4.1. Согласованность Ack Vector

Отправитель DCCP обычно будет получать многочисленные подтверждения для некоторых отправленных им пакетов данных. Например, HC-Sender может получить два пакета DCCP-Ack с опциями Ack Vector, каждый из которых будет содержать информацию о порядковом номере 24 (информация о порядковом номере обычно повторяется в каждом подтверждении, пока HC-Sender не подтвердит получение подтверждения; в этом случае HC-Receiver передает подтверждения быстрее, чем HC-Sender подтверждает их получение). В идеальном мире две опции Ack Vector всегда будут согласованы. Однако существует множество причин, по которым согласования может не быть.

  • Получатель HC-Receiver принял пакет 24 в промежутке между передачей своих подтверждений и в первом он указал, что пакет 24 не принят (State 3), а во втором указал статус ECN (State 0 или 1).
  • Получатель HC-Receiver принял пакет 24 в промежутке между передачей своих подтверждений, а порядок доставки этих подтверждений был нарушен в сети. В этом случае пакеты будут представляться как сменившие State 0 или 1 на State 3.
  • В сети возникли дубликаты пакета 24 и один или несколько таких дубликатов имеют маркер ECN. Это может представляться как переход между состояниями 0 и 1.

Чтобы справиться с такими ситуациями реализации DCCP на стороне HC-Sender следует объединять множество полученных состояний Ack Vector, как показано на рисунке.

   Полученное состояние
            0   1   3
          +---+---+---+
        0 | 0 |0/1| 0 |
  Прежнее +---+---+---+
        1 | 1 | 1 | 1 |
состояние +---+---+---+
        3 | 0 | 1 | 3 |
          +---+---+---+

Для чтения таблицы выбирается строка, соответствующая старому состоянию пакета, и колонка, соответствующая состоянию пакета в недавно полученной опции Ack Vector; пересечение покажет новое состояние пакета. Если старое состояние было 0 (принят немаркированный пакет), а новое – 1 (пакет принят с маркером ECN), в качестве нового состояния следует установить 0 или 1. Реализация HC-Sender будет безразлична к изменению порядка доставки подтверждений, если она выберет для данной ячейки в качестве нового состояния 1.

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

           Принятый пакет
              0   1   3
            +---+---+---+
          0 | 0 |0/1| 0 |
Сохраненное +---+---+---+
          1 |0/1| 1 | 1 |
состояние +---+---+---+
          3 | 0 | 1 | 3 |
            +---+---+---+

Эта таблица отличается от таблицы для отправителя лишь тем, что когда сохраненное состояние равно 1, а полученное – 0, получатель может сменить сохраненное состояние на 0.

HC-Sender может выбрать отказ от старой информации, собранной из полученных от HC-Receiver опций Ack Vector; в этом случае отправитель должен игнорировать полученные недавно от HC-Receiver подтверждения для тех старых пакетов. Представляется более разумным сохранение информации Ack Vector, чтобы отправитель HC-Sender мог отказаться от своей реакции на предполагаемое насыщение, когда «потерянный» пакет неожиданно найдется (смена State 3 на State 0).

11.4.2. Покрытие Ack Vector

Можно разбить пакеты, переданные от HC-Sender получателю HC-Receiver, на 4 почти непрерывные группы. Начиная с наиболее старых пакетов это будут:

  1. пакеты, уже подтвержденные HC-Receiver, для которых HC-Receiver знает, что отправитель HC-Sender определенно получил подтверждения;
  2. пакеты, уже подтвержденные HC-Receiver, для которых HC-Receiver не имеет уверенности в том, что отправитель HC-Sender уже получил подтверждения;
  3. пакеты, которые получатель HC-Receiver еще не подтвердил;
  4. пакеты, еще не полученные HC-Receiver.

Объединение групп 2 и 3 называется окном подтверждения (Acknowledgement Window). В общем случае каждая опция Ack Vector, генерируемая HC-Receiver, будет покрывать все окно Acknowledgement Window – подтверждения Ack Vector являются кумулятивными (это упрощает поддержку Ack Vector на стороне HC-Receiver; см. Приложение A). По мере доставки пакетов это окно будет расширяться справа и сужаться слева. Окно расширяется по причине доставки новых пакетов и сужается в результате того, что номера подтверждений HC-Sender будут подтверждать более ранние подтверждения, перемещая пакеты из группы 2 в группу 1.

11.5. Признак Send Ack Vector

Признак Send Ack Vector позволяет точкам DCCP согласовать использование опции Ack Vector для передачи информации о насыщении. Опции Ack Vector обеспечивают подробную информацию о потерях пакетов и позволяют отправителю проинформировать прикладную программу на своей стороне о том, что некоторые пакеты были отброшены. Признак Send Ack Vector является обязательным для некоторых CCID и необязательным для остальных.

Признак Send Ack Vector имеет номер 6 и устанавливается с приоритетом сервера. Признак принимает однобайтовые логические значения. Точка DCCP A должна передавать опции Ack Vector в своих подтверждениях, если Send Ack Vector/A = 1, хотя она может передавать опции Ack Vector даже в случае Send Ack Vector/A = 0. Значения признака 2 и более являются резервными. Новые соединения начинаются с Send Ack Vector 0 для обеих сторон. DCCP B передает опцию Change R(Send Ack Vector, 1) точке DCCP A для запроса у A передачи опций Ack Vector в пакетах подтверждений.

11.6. Опция Slow Receiver

HC-Receiver передает опцию Slow Receiver своему отправителю, чтобы сказать о возникновении проблем при приеме данных от того. Отправителю HC-Sender не следует повышать скорость передачи в течение приблизительно одного периода кругового обхода после получения пакета с опцией Slow Receiver. По истечении одного периода кругового обхода действие опции Slow Receiver прекращается и HC-Sender может повышать скорость. Поэтому получателю HC-Receiver следует продолжать передачу опций Slow Receiver, если ему требуется предотвратить повышение скорости передачи в течение продолжительного срока. Опция Slow Receiver не говорит о насыщении в сети и отправителю HC-Sender не требуется снижать скорость передачи (при необходимости получатель может вынудить отправителя к снижению скорости путем отбрасывания пакетов с передачей опции Data Dropped или без нее, а также путем установки фиктивных маркеров ECN). Интерфейсам API следует позволять принимающим приложениям устанавливать опцию Slow Receiver, а передающим приложениям – определять наличие этой опции в пакетах.

Опция Slow Receiver является однобайтовой, как показано на рисунке.

   +--------+
   |00000010|
   +--------+
    Type=2

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

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

Опция Slow Receiver частично реализует функции окна приема TCP.

11.7. Опция Data Dropped

Опция Data Dropped показывает, что данные приложения из одного или множества полученных пакетов на самом деле не были доставлены приложению. Кроме того, Data Dropped сообщает причину отбрасывания данных – возможно они оказались поврежденными или получатель неспособен принимать информацию с той скоростью, которую установил отправитель и данные были отброшены приемным буфером. С помощью опции Data Dropped конечные точки DCCP могут отличать разные варианты потери пакетов. Это отличается от протокола TCP, в котором информация о потере пакетов единообразна.

Если явно не указано иное, механизмы контроля насыщения DCCP должны реагировать на опции Data Dropped, как будто пакеты были помечены в сети маркерами ECN CE. Мы предполагаем, что опция Data Dropped позволит исследовать отклики в условиях сильного насыщения на повреждения и отбрасывание конечными точками пакетов, но механизмы CCID должны консервативно реагировать на опции Data Dropped, пока это поведение не стандартизовано. В параграфе 11.7.2 обсуждаются отклики на перегрузки для всех определенных в настоящее время значений Drop Code.

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

Вид данных опции показан на рисунке.

   +--------+--------+--------+--------+--------+--------
   |00101000| Length | Block  | Block  | Block  |  ...
   +--------+--------+--------+--------+--------+--------
    Type=40          \___________ Vector ___________ ...

Область Vector содержит последовательности байтов, называемые блоками, каждая из которых кодируется в соответствии с одним из двух показанных на рисунке вариантов.

 0 1 2 3 4 5 6 7            0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+          +-+-+-+-+-+-+-+-+
|0| Run Length  |   или    |1|DrpCd|Run Len|
+-+-+-+-+-+-+-+-+          +-+-+-+-+-+-+-+-+
 Нормальный блок           Отброшенный блок

Первый байт опции Data Dropped относится к пакету, указанному полем Acknowledgement Number, а последующие байты относятся к более старым пакетам. Опции Data Dropped недопустимо включать в пакеты DCCP-Data и DCCP-Request, которые не включают поля Acknowledgement Number, и все опции Data Dropped, полученные в таких пакетах, должны игнорироваться.

Нормальные блоки, старший бит которых имеет значение 0, показывают, что все пакеты, указанные полем Run Length, были доставлены приложению. Отброшенные блоки, старший бит которых имеет значение 1, показывают, что пакеты, указанные в поле Run Len, не были доставлены приложению. Трехбитовое поле DrpCd6 указывает, что произошло (в общем случае данные из пакета не были доставлены приложению). Пакеты, указанные как «еще не полученные», должны включаться в нормальные блоки; пакеты, не включенные ни в одну из опций Data Dropped, трактуются, как будто они были включены в Normal Block. Определенные значения кодов отбрасывания для отброшенных блоков показаны в таблице 7.

Таблица 7: Коды отбрасывания пакетов DCCP

Код причины Название

0

Protocol Constraints

1

Application Not Listening

2

Receive Buffer

3

Corrupt

4 – 6

Резерв

7

Delivered Corrupt

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

0 – данные из пакета были отброшены в результате протокольных ограничений. Например, данные были включены в пакет DCCP-Request, но принимающее приложение не поддерживает такую возможность, или данные были включены в пакет с недопустимо низким значением Checksum Coverage.

1 – данные были отброшены по той причине, что приложение больше не находится в режиме прослушивания (см. параграф 11.7.2).

2 – данные из пакета были отброшены в приемном буфере, возможно в результате его переполнения (см. параграф 11.7.2).

3 – данные из пакета были отброшены по причине их повреждения (см параграф 9.3).

7 – данные из пакета оказались поврежденными, но были доставлены приложению (см. параграф 9.3).

В качестве примера рассмотрим пакет, прибывающий с Acknowledgement Number 100, опцией Ack Vector, сообщающей, что все пакеты получены, и опцией Data Dropped, содержащей десятичные значения 0,160,3,162.

пакет 100 был получен (Acknowledgement Number 100, Normal Block, Run Length 0).

пакет 99 был отброшен в приемном буфере (Drop Block, Drop Code 2, Run Length 0).

пакеты 98, 97, 96, 95 были получены (Normal Block, Run Length 3).

пакеты 95, 94, 93 были отброшены в приемном буфере (Drop Block, Drop Code 2, Run Length 2).

Значения Run length, превышающие 128 (для Normal Block) или 16 (для Drop Block), должны кодироваться с использованием нескольких блоков. Одна опция Data Dropped может подтверждать до 32384 нормальных блоков, хотя получателю не следует передавать опцию Data Dropped, когда все относящиеся к делу пакеты помещаются в нормальные блоки. Если требуется подтвердить больше пакетов, нежели можно поместить в 253 байта опции Data Dropped, можно передавать множество опций Data Dropped. Вторая опция будет начинаться там, где закончится первая и т. д.

Одна или множество опций Data Dropped вместе могут сообщать о состоянии большего числа пакетов, нежели было передано, менять состояние для пакетов, вступать в противоречие с Ack Vector или эквивалентными опциями (например, сообщая о пакетах, которые еще не доставлены, как об отброшенных в приемном буфере). Такие опции следует рассматривать как некорректные. Принимающей стороне DCCP следует игнорировать такие опции или сбрасывать соединение с Reset Code 5, Option Error.

Прикладному интерфейсу DCCP следует позволять принимающему приложению задавать значения Drop Code, соответствующие полученным пакетам. Например, это позволит приложениям рассчитывать свои контрольные суммы, но продолжать уведомлять об отбрасывании пакетов в результате повреждения с помощью опции Data Dropped. Интерфейсу не следует позволять приложениям снижать «значимость» Drop Code; например, приложению не следует позволять менять для пакета состояние с «поврежден при доставке» (Drop Code 7) на «доставлен нормально» (нет Drop Code).

Информация Data Dropped передается с гарантией доставки. Т. е., конечной точке следует продолжать передачу опций Data Dropped до получения подтверждения, показывающего, что соответствующие опции были обработаны. В терминах Ack Vector каждому подтверждению следует включать опции Data Dropped, которые покрывают все окно подтверждений (Acknowledgement Window, см. параграф 11.4.2), хотя в тех случаях, когда все пакеты из этого окна помещаются в нормальный блок, опция не требуется.

11.7.1. Отклик на Data Dropped и обычный отклик на перегрузку

При решении вопроса об отклике на отдельное подтверждение или набор подтверждений, содержащих опции Data Dropped, механизм контроля насыщения должен принимать во внимание отброшенные пакеты, пакеты с маркерами ECN CE (включая маркированные пакеты, которые указаны в опции Data Dropped) и пакеты, отдельно указанные в Data Dropped. Для основанных на использовании окна механизмов контроля насыщения корректные отклики определены ниже.

Обозначим старое окно W. Независимо рассчитаем новое окно W_new1, которое предполагает отсутствие пакетов Data Dropped (W_new1 содержит только обычный отклик на насыщение), и новое окно W_new2, которое предполагает отсутствие потерянных или помеченных пакетов (W_new2 содержит только отклик Data Dropped). Мы полагаем, что Data Dropped рекомендует снижение размера окна насыщения, поэтому W_new2 < W.

Тогда реальное новое окно W_new недопустимо делать больше минимального из двух значений W_new1 и W_new2, а отправитель может объединить два отклика, установив

W_new = W + min(W_new1 - W, 0) + min(W_new2 - W, 0)

Детальное описание этой процедуры задается в спецификациях профилей CCID. Механизмы контроля насыщения, не использующие окно, должны вести себя аналогично. Точное поведение опять-таки определяется профилем CCID.

11.7.2. Отдельные значения Drop Code

Drop Code 0, Protocol Constraints7 не указывает на какой-либо тип насыщения, поэтому механизму CCID на стороне отправителя следует реагировать на пакеты с Drop Code 0, как на принятые пакеты (с маркером ECN CE или без него, как подходит). Однако передающей конечной точке не следует передавать данные, пока она не убедится, что протокольные ограничения более не применимы.

Drop Code 1, Application Not Listening8 означает, что приложение на той стороне, которая передала опции, более не принимает данные. Например, сервер мог закрыть свое приемное полусоединение для получения новых данных после приема от клиента запроса на завершение. Это будет ограничивать число состояний сервера для входящих данных и, следовательно, снижать риск повреждений в результате некоторых атак на службы. Опцию Data Dropped с Drop Code 1 следует передавать всякий раз, когда полученные данные игнорируются в результате того, что приложение прекратило прослушивание входящей информации. После того, как конечная точка передала для пакета уведомление с Drop Code 1, ей следует передавать этот код для всех последующих пакетов в данном полусоединении. После получения конечной точкой уведомления с Drop State 1, ей следует ожидать, что другая сторона больше не предполагает получение данных и их не следует передавать.

Drop Code 2, Receive Buffer показывает, что насыщение произошло на приемном хосте. Например, если буфер сокета ядра, работающий по принципу отбрасывания из конца, слишком заполнен, чтобы принимать данные, следует передавать уведомление с Drop Code 2. Для буферов с отбрасыванием из начала или более сложных вариантов буферизации для сокета ядра, уведомлять об отбрасывании пакетов следует с Drop Code 2. Реализации DCCP могут также предоставлять интерфейс API, с помощью которого приложения могут помечать полученные пакеты, как Drop Code 2, показывая, что приложение выходит за допустимые пределы приемного буфера в пользовательском пространстве (однако в общем случае не будет пользы от передачи уведомлений об отбрасывании пакетов с Drop Code 2 после того, как пройдет более 2 периодов кругового обхода; HC-Sender может забыть за это время состояния подтверждения для пакетов, поэтому уведомление Data Dropped не будет оказывать влияния). На каждый пакет, о котором получено уведомление с Drop Code 2, следует уменьшать мгновенную скорость передачи на один пакет за период кругового обхода, если скорость больше одного пакета за время RTT. Каждый профиль CCID определяет специфический для данного CCID механизм, который обеспечивает это снижение скорости.

В настоящее время другие значения Drop Code (а именно, Drop Code 3, Corrupt; Drop Code 7, Delivered Corrupt и резервные значения 4-6) должны заставлять соответствующий механизм CCID вести себя, как при получении пакетов с маркерами ECN CE.

12. Явное уведомление о насыщении

Протокол DCCP полностью поддерживает ECN [RFC3168]. Каждый CCID задает для конечных точек способ отклика на маркировку ECN. Более того, DCCP, в отличие от TCP, позволяет отправителю контролировать скорость генерации подтверждений (с помощью опций типа Ack Ratio); поскольку для подтверждений также применяется контроль насыщения, они также квалифицируются как ECN-Capable Transport.

Каждый профиль CCID описывает, как CCID взаимодействует с ECN для трафика данных и для «чистых» пакетов подтверждения. Отправителю следует устанавливать флаг ECN-Capable Transport в заголовках IP своих пакетов, если признак получателя ECN Incapable для соответствующего CCID не запрещает это.

Остальная часть этой главы описывает признак ECN Incapable и взаимодействие ECN Nonce с опциями подтверждения, такими, как Ack Vector.

12.1. Признак ECN Incapable

Конечные точки DCCP поддерживают ECN по умолчанию, но признак ECN Incapable позволяет конечной точке отвергнуть использование явных уведомлений о насыщении. Использовать этот признак не рекомендуется. Несовместимость с ECN не позволит использовать возможные преимущества ECN и лишит отправителей возможности использования ECN Nonce для проверки корректности поведения получателей. Стек DCCP может, следовательно, оставить признак ECN Incapable нереализованным, действуя так, будто все соединения поддерживают ECN. Отметим, что недопустимое взаимодействие МСЭ, обманывающее реализации ECN в TCP [RFC3360], использует биты заголовка TCP, а не биты ECN в заголовке IP; нам не известно промежуточных устройств, которые будут блокировать поддерживающие ECN пакеты DCCP, разрешая передачу несовместимых с ECN пакетов DCCP.

Признак ECN Incapable имеет номер 4 и устанавливается с приоритетом сервера. Признак принимает однобайтовые логические значения. Точка DCCP A должна быть способна читать биты ECN в заголовках IP полученных кадров, когда ECN Incapable/A = 0 (это не зависит от возможности установки данной точкой битов ECN в передаваемых ею кадрах). Точка DCCP A будет передавать опцию Change L(ECN Incapable, 1) точке DCCP B, чтобы проинформировать ту о том, что A не может читать биты ECN. Если ECN Incapable/A = 1, все пакеты от DCCP B должны передаваться, как несовместимые с ECN. Новые соединения начинаются с ECN Incapable 0 (т. е., ECN поддерживается) для обеих сторон. Значения признака 2 и более зарезервированы.

Если точка DCCP не поддерживает ECN, она должна передавать обязательную опцию Change L(ECN Incapable, 1) другой конечной точке до получения от той подтверждения в опции Confirm R(ECN Incapable, 1) или разрыва соединения. Более того, недопустимо принимать какие-либо данные, пока другая точка не передаст опцию Confirm R(ECN Incapable, 1). Следует передавать в подтверждении опцию Data Dropped с Drop Code 0 (протокольные ограничения), если другая точка шлет данные до передачи требуемой опции.

12.2. Сигналы ECN Nonce

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

Сигналы ECN Nonce представляют собой механизм общего назначения, предотвращающий сокрытие ECN (или потери пакетов). Два значения (01 и 10) двухбитового поля ECN в заголовке показывают ECN-Capable Transport. Второй код (10) используется, как ECN Nonce. В общем случае отправитель случайно выбирает один из этих двух кодов для включения в передаваемые пакеты, запоминая последовательность этих кодов. В каждом подтверждении получатель указывает число полученных сигналов ECN Nonce. Это называется ECN Nonce Echo. Поскольку маркировка ECN и отбрасывание пакетов удаляют ECN Nonce, получатель, желающий скрыть маркировку или отбрасывание пакетов, может с вероятностью 50% угадать состояние ECN Nonce и избежать наказания за обман. Отправитель может жестко реагировать на несоответствие ECN Nonce, вплоть до сброса соединения. Поле ECN Nonce Echo не обязательно должно быть целым числом – достаточно 1 бита для обнаружения подмены с вероятностью 50% и вероятность обнаружения обмана экспоненциально возрастает по мере увеличения числа переданных пакетов [RFC3540].

В DCCP поле ECN Nonce Echo включается в опции подтверждения. Например, опция Ack Vector существует в 2 вариантах – Ack Vector [Nonce 0] (опция 38) и Ack Vector [Nonce 1] (опция 39), – соответствующих двум значениям однобитового поля ECN Nonce Echo. Значение Nonce Echo для данной опции Ack Vector равно однобитовой сумме (четность или «исключающее ИЛИ») значений ECN nonce для пакетов, которые Ack Vector показывает, как принятые без маркеров ECN. Таким образом, лишь пакеты, указанные, как State 0 (принятые корректные пакеты без маркера ECN), принимаются во внимание при вычислении суммы. Каждая опция Ack Vector содержит достаточную информацию, чтобы отправитель мог определить, каким должно быть значение Nonce Echo. Отправитель может заново рассчитать значение Nonce Echo, сравнить с полученным и принять меры при наличии расхождения (опция Ack Vector может сообщать состояние ECN Nonce для каждого пакета, но это будет ограничивать сжимаемость опции без обеспечения дополнительной защиты).

Каждому отправителю DCCP следует устанавливать биты ECN Nonce в передаваемых пакетах и запоминать пакеты, имеющие nonce. Когда отправитель детектирует несоответствие ECN Nonce Echo, он ведет себя, как описано в следующем параграфе. Каждый получатель DCCP должен рассчитывать и использовать корректное значение для бита ECN Nonce Echo при отправке опций подтверждения.

Несовместимость с ECN, указанная признаком ECN Incapable, обрабатывается следующим образом – конечная точка, передающая пакеты не поддерживающему ECN получателю, должна передавать свои пакеты как несовместимые с ECN, а получатель, который не поддерживает ECN, должен использовать нулевое значение для всех битов ECN Nonce Echo.

12.3. Наказания за агрессию

Конечные точки DCCP имеют несколько механизмов детектирования некорректного поведения в связи с контролем насыщения. Например,

  • отправитель может обнаружить несоответствие ECN Nonce Echo, говорящее, возможно, о некорректном поведении получателя;
  • получатель может определить, реагирует ли отправитель на сигналы о насыщении или опцию Slow Receiver;
  • конечная точка может быть способна детектировать, что ее партнер сообщает недопустимо малые значения Elapsed Time (параграф 13.2).

Конечной точке, обнаружившей предположительно некорректное поведение в части контроля насыщения, следует попытаться проверить корректность поведения партнера. Например, передающая сторона может отправить пакет, в котором поле заголовка ECN имеет значение Congestion Experienced, 11 – если отправитель не сообщит о маркировке пакета, это будет говорить о его некорректном поведении.

После обнаружения предположительно некорректного поведения отправителю следует реагировать на него, как при получении от партнера уведомления о маркировке ECN для одного или нескольких недавних пакетов. Получателю, обнаружившему предположительно некорректное поведение, следует сообщить о наличии маркеров ECN в одном или нескольких недавних пакетах, которые на самом деле не имели маркеров. Кроме того, в таких случаях отправитель может реагировать, как при получении опции Slow Receiver, а получатель может передавать опции Slow Receiver. Допустимы и другие меры, способные снизить скорость передачи данных. Точка, обнаружившая грубые случаи некорректного поведения, может также сбросить соединение с использованием Reset Code 11, Aggression Penalty.

Однако несоответствие ECN Nonce и другие сигналы могут быть результатом неумышленных действий, ошибок в реализации или атак. В частности, успешная атака DCCP-Data (параграф 7.5.5) может приводить к тому, что получатель будет передавать некорректные значения ECN Nonce Echo. Поэтому сброс соединений и другие жесткие меры следует применять только в крайних случаях, когда агрессивное поведение наблюдается в течение многих периодов кругового обхода.

13. Опции синхронизации

Опции Timestamp, Timestamp Echo и Elapsed Time помогают конечным точка DCCP явно измерять время кругового обхода.

13.1. Опция Timestamp

Эту опцию можно использовать в пакетах DCCP любого типа. Размер опции составляет 6 байтов.

   +--------+--------+--------+--------+--------+--------+
   |00101001|00000110|          Timestamp Value          |
   +--------+--------+--------+--------+--------+--------+
    Type=41  Length=6

Четыре байта данных опции позволяют включить в пакет временную метку. Метка представляет собой 32-битовое целое число, которое монотонно возрастает с течением времени (каждые 10 мксек на 1). При такой скорости значение Timestamp Value будет достигать максимума и сбрасываться в 0 приблизительно каждые 11,9 часа. Конечным точка не требуется измерять время с точностью 10 мксек; например, конечная точка, предпочитающая измерять время с дискретностью 1 мсек, может просто передавать значения Timestamp Value, кратные 100. Точное время, соответствующее Timestamp Value = 0, не задается – Timestamp Value имеет смысл лишь относительно значений Timestamp Value в пакетах, переданных через данное соединение. Точке DCCP, принявшей опцию Timestamp, следует включить в следующий передаваемый пакет опцию Timestamp Echo.

13.2. Опция Elapsed Time

Эта опция может включаться в любые пакеты DCCP, имеющие поле Acknowledgement Number; при получении опции в других пакетах, она должна игнорироваться. Опция показывает время, прошедшее с момента получения подтверждаемого пакета, который указывает поле Acknowledgement Number. Опция может занимать 4 или 6 байтов в зависимости от значения Elapsed Time. Опция Elapsed Time помогает корректировать оценку времени кругового обхода, когда интервал между приемом и подтверждением пакета может быть достаточно велик (например, в CCID 3, где подтверждения передаются достаточно редко).

   +--------+--------+--------+--------+
   |00101011|00000100|   Elapsed Time  |
   +--------+--------+--------+--------+
    Type=43    Len=4

   +--------+--------+--------+--------+--------+--------+
   |00101011|00000110|            Elapsed Time           |
   +--------+--------+--------+--------+--------+--------+
    Type=43    Len=6

Поле данных опции, Elapsed Time, представляет оценку нижней границы времени, прошедшего с момента приема подтверждаемого пакета в сотых долях миллисекунды (10 мксек). Если Elapsed Time меньше 0,5 сек, следует использовать 4 байтовый вариант опции. Значения Elapsed Time больше 0,65535 сек должны передаваться с использованием 6-байтового формата. Специальное значение Elapsed Time = 4294967295, которое соответствует приблизительно 11,9 часа, используется для представления времени, превышающего 42949,67294 сек. Для конечных точек DCCP недопустимо передавать значения Elapsed Time, существенно превышающее реальное время задержки между приемом и подтверждением пакета. Соединение может быть сброшено с Reset Code 11, Aggression Penalty, если одна из сторон определит, что другая указала слишком большое значение Elapsed Time.

Единица измерения Elapsed Time (10 мксек) была выбрана, как компромисс между двумя противоречивыми требованиями. С одной стороны, обеспечивается достаточная гранулярность для снижения ошибок округления при использовании в скоростных средах ЛВС. С другой стороны, в два байта можно поместить информацию о большинстве разумных значений задержки.

13.3. Опция Timestamp Echo

Эту опцию можно использовать в любых пакетах DCCP при получении хотя бы одного пакета с опцией Timestamp. В общем случае конечной точке DCCP следует передавать одну опцию Timestamp Echo для каждой принятой опции Timestamp, делая это так, как будет удобно. Размер опции может составлять от 6 до 10 байтов, в зависимости от величины включаемого в нее значения Elapsed Time.

   +--------+--------+--------+--------+--------+--------+
   |00101010|00000110|           Timestamp Echo          |
   +--------+--------+--------+--------+--------+--------+
    Type=42    Len=6

   +--------+--------+------- ... -------+--------+--------+
   |00101010|00001000|  Timestamp Echo   |   Elapsed Time  |
   +--------+--------+------- ... -------+--------+--------+
    Type=42    Len=8       (4 байта)

   +--------+--------+------- ... -------+------- ... -------+
   |00101010|00001010|  Timestamp Echo   |    Elapsed Time   |
   +--------+--------+------- ... -------+------- ... -------+
    Type=42   Len=10       (4 байта)           (4 байта)

Первые 4 байта данных опции (поле Timestamp Echo) содержат поле Timestamp Value из полученной последней опции Timestamp. Обычно эта опция берется из последнего принятого пакета (указываемого полем Acknowledgement Number, если оно присутствует), но это может быть и предшествующий пакет. Каждая принятая опция Timestamp в общем случае ведет к передаче в ответ одной опции Timestamp Echo. Если точка получила множество опций Timestamp с момента передачи последнего пакета, она может игнорировать все опции Timestamp, используя только одну – из пакета с максимальным порядковым номером. Можно также включить в пакет множество опций Timestamp Echo, каждая из которых будет соответствовать своей опции Timestamp.

Значение Elapsed Time, подобно опции Elapsed Time, показывает время, прошедшее с момента получения опции, для которой передается ответная опция. Это время должно измеряться в сотых долях миллисекунды (10 мксек). Значение Elapsed Time предназначено для того, чтобы помочь отправителю опции Timestamp вычесть из времени кругового обхода время обработки на стороне приема опции Timestamp. Эта возможность может оказаться особо важной для CCID, в которых подтверждения передаются достаточно редко и может пройти много времени между получением опции Timestamp и передачей ответной опции Timestamp Echo. Отсутствие поля Elapsed Time трактуется, как Elapsed Time = 0. Следует использовать наименьший по размеру вариант опции, позволяющий поместить значение Elapsed Time.

14. Максимальный размер пакета

Реализация DCCP должна поддерживать значение максимального размера пакета (MPS9), разрешенного для каждой активной сессии DCCP. Значение MPS определяется максимальным размером пакета, разрешаемым механизмом контроля насыщения (CCMPS10), максимальным размером пакета, поддерживаемым используемыми для сессии путями (PMTU11) [RFC1191] и размером заголовков IP и DCCP.

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

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

14.1. Измерение PMTU

Каждая точка DCCP должна отслеживать текущее значение PMTU для каждого из своих соединений, за исключением соединений IPv4, в которых приложения запросили фрагментацию пакетов. При инициализации PMTU следует использовать значение MTU для интерфейса, через который будут передаваться пакеты. Для инициализации MPS используется меньшее из значений PMTU и CCMPS (если оно существует).

Классический механизм определения PMTU использует нефрагментируемые пакеты. В IPv4 такие пакеты используют флаг DF12, а в IPv6 все пакеты становятся нефрагментируемыми после того, как покинут исходный хост. Как сказано в [RFC1191], когда маршрутизатор получает пакет с флагом DF, размер которого превышает значение MTU для следующего отрезка пути, он возвращает отправителю сообщение ICMP Destination Unreachable, в котором поле Code показывает, что размер нефрагментируемого пакета слишком велик для пересылки (сообщение Datagram Too Big). Когда реализация DCCP получает сообщения Datagram Too Big, она снижает свое значение PMTU до значения поля Next-Hop MTU в полученном сообщении ICMP. Если в сообщении указано MTU = 0, отправитель выбирает значение PMTU на основе алгоритма, описанного в главе 7 [RFC1191]. Если полученное в сообщении значение MTU превышает текущее значение PMTU, сообщение Datagram Too Big игнорируется, как описано в [RFC1191] (мы полагаем, что это может вызывать проблемы для конечных точек DCCP, расположенных за некоторыми типами МСЭ).

Реализация DCCP может разрешать приложению время от времени запрашивать повторное определение PMTU. Это будет приводить к установке для PMTU значения MTU выходного интерфейса. Частоту таких запросов следует ограничивать (например, не более одного запроса в течение 2 сек.).

Отправитель DCCP может трактовать получение сообщения ICMP Datagram Too Big, как индикацию того, что пакет не был потерян в результате насыщения и, в целях контроля насыщения, может игнорировать сигнал получателя DCCP о том, что пакет не был получен. Однако в этом случае отправитель DCCP должен проверять биты ECN в заголовке пакета IP, содержащегося в сообщении ICMP, и игнорировать уведомление получателя только в том случае, когда эти биты ECN показывают, что пакет не сталкивался с насыщением до того, как попал на маршрутизатор, неспособный переслать пакет по причине превышения MTU.

Реализации DCCP следует всякий раз, когда это возможно, проверять, что сообщения ICMP Datagram Too Big действительно сгенерированы маршрутизаторами, поскольку атакующие могут снижать PMTU до недопустимо малых значений. Простейшим способом является проверка соответствия значения Sequence Number инкапсулированного в сообщении ICMP заголовка порядковым номерам пакетов, недавно переданных отправителем (в соответствии с современными спецификациями маршрутизаторам следует возвращать полный заголовок DCCP и данные из пакета, общим размером до 576 байтов [RFC1812] или минимальное значение IPv6 MTU [RFC2463], хотя не обязательно возвращать более 64 битов [RFC792]; любое количество данных, превышающее 128 битов, будет включать поле Sequence Number). Сообщения ICMP Datagram Too Big с некорректными или отсутствующими порядковыми номерами можно игнорировать или снижать в ответ на них значение PMTU лишь на короткое время. Если получено 3 или более разрозненных сообщения Datagram Too Big и другая конечная точка DCCP сообщает о том, что потеряно более 3 пакетов, реализации DCCP следует предполагать наличие плохо настроенного маршрутизатора и принимать указанное в сообщениях ICMP значение PMTU или (для IPv4) разрешать фрагментацию пакетов.

DCCP также допускает нарастающие пробы PMTU [PMTUD], при которых конечная точка DCCP начинает передавать мелкие пакеты с флагом DF и постепенно увеличивает размер пакетов до первой потери. Этот механизм не требует обработки сообщений ICMP. Пакеты DCCP-Sync лучше всего подходят для нарастающих проб, поскольку передача таких пакетов не связана с риском потери данных. Реализация DCCP помещает произвольную информацию в область данных DCCP-Sync, создавая пакеты нужного размера. Поскольку каждый корректный пакет DCCP-Sync вызывает незамедлительную генерацию ответного пакета DCCP-SyncAck, конечная точка сможет легко зафиксировать потерю пакета.

14.2. Поведение отправителя

Отправителю DCCP следует передавать пакеты нефрагментируемыми, как описано выше, за исключением следующих случаев.

  • На соединениях IPv4, где приложения запросили фрагментацию, отправителю следует передавать пакеты со сброшенным флагом DF.
  • На соединениях IPv6, где приложения запросили фрагментацию, отправителю следует использовать специальное расширение для фрагментации пакетов, превышающих по размеру значение PMTU, в блоки подходящего размера (блоки, естественно, являются нефрагментируемыми).
  • Нежелательно определять PMTU на этапе начального согласования параметров соединения, поскольку процесс организации соединения может не представлять размера пакетов, которые будут использоваться в соединении, а выполнение процедур определения MTU для пути через сеть может слишком затянуть процесс организации соединения. Таким образом, пакеты DCCP-Request и DCCP-Response следует передавать как фрагментируемые. Кроме того, пакеты DCCP-Reset следует передавать как фрагментируемые, хотя обычно они достаточно малы и не требуют фрагментации. Для соединений IPv4 такие пакеты следует передавать со сброшенным флагом DF, а для соединений IPv6 пакеты следует заранее фрагментировать до размера, не превышающего значение MTU для выходного интерфейса.

Если реализация DCCP снижает значение PMTU, а передающее приложение не запросило фрагментацию и размер пакета превышает новое значение MPS, интерфейс API должен отвергнуть передачу пакета и возвратить соответствующее сообщение об ошибке. Приложению после этого следует, используя API, запросить новое значение MPS. Ядро может содержать в буфере передачи пакеты, размер которых меньше старого значения MPS, но превышает новое значение. Эти пакеты можно передать как фрагментируемые или отбросить, но недопустимо передавать эти пакеты с запретом фрагментации.

15. Совместимость с будущими версиями

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

  • Для процессоров DCCP недопустимо использование карательных мер в отношении непонятных опций и признаков. Например, процессору DCCP недопустимо сбрасывать соединение, если некоторые поля, указанные в этой спецификации, как резервные, имеют отличные от 0 значения. Вместо этого процессор DCCP должен игнорировать такие поля. Обязательные опции или признаки являются единственным исключением – если опция Mandatory предшествует непонятной опции или признаку, соединение должно быть сброшено.
  • Процессоры DCCP должны допускать возможность присутствия неизвестных значений, которые могут появляться при согласовании известных признаков. Для признаков, устанавливаемых с приоритетом сервера, неизвестные значения обрабатываются, как сами собой разумеющиеся – поскольку стандартный (не расширенный) список предпочтений DCCP не будет содержать неизвестных значений, результат обязательно будет из числа известных. Реализация DCCP должна возвращать пустую опцию Confirm при получении неизвестного значения для признака, не использующего согласования.
  • Каждое расширение DCCP следует контролировать с помощью того или иного признака. По умолчанию для этого признака следует использовать значение extension not available13. Если расширенная реализация DCCP хочет использовать это расширение, ей следует предпринять попытку изменить значение этого признака с помощью опции Change L или Change R. Стандартные (не расширенные) реализации DCCP будут игнорировать опцию и для признака сохранится значение extension not available.

В главе 19 перечислены значения, выделенные для экспериментов и тестирования DCCP.

16. Промежуточные устройства

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

Поле Service Code в пакетах DCCP-Request обеспечивает информацию, которая может быть полезна промежуточным устройствам, учитывающим состояние соединений. На основании Service Code промежуточная точка может определить используемый в соединении протокол, не опираясь на номера портов. Промежуточные устройства могут блокировать соединения, пытающиеся получить доступ к нежелательным службам, передавая пакет DCCP-Reset с Reset Code 8, Bad Service Code. Промежуточным узлам не следует менять значения поля Service Code, если они реально не подменяют службу, к которой обращается соединение.

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

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

Изменение полей Sequence Number и Acknowledgement Number в DCCP является более утомительным и опасным, нежели изменение порядковых номеров TCP. Промежуточные устройства, добавляющие или удаляющие пакеты из соединений DCCP, должны как минимум изменить опции подтверждения, такие, как Ack Vector, и связанные с CCID опции типа Loss Interval для TFRC. На поддерживающих ECN соединениях промежуточным устройствам нужно отслеживать информацию ECN Nonce для добавляемых или удаляемых пакетов, так, чтобы соответствующие опции подтверждений продолжали сохранять корректные значения ECN Nonce Echo, поскольку в противном случае соединение может быть сброшено за «агрессивное поведение». Мы, следовательно, рекомендуем промежуточным узлам не изменять поток пакетов путем добавления или удаления пакетов.

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

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

Протокол DCCP не совсем дружелюбен к «слиянию соединений» [SHHP00], при котором клиентские попытки организации соединений перехватываются, но позднее могут «приращиваться» к соединениям с внешними серверами путем манипуляций с порядковыми номерами. Для слияния соединений нужно обеспечить по крайней мере согласие со всеми относящимися к делу признаками, что может потребовать повторного согласования.

Содержимое этой главы не следует воспринимать как рекламу промежуточных устройств с учетом состояния соединений.

17. Связь с другими спецификациями

17.1. RTP

Протокол RTP14 [RFC3550] в настоящее время используется на базе транспорта UDP многими приложениями, подходящими для DCCP (например, потоковое вещание). Следовательно, важно рассмотреть отношения между протоколами DCCP и RTP и, в частности, вопрос о необходимости внесения изменений в RTP при переходе на транспорт DCCP взамен UDP.

Имеются два потенциальных источника дополнительных издержек при использовании RTP на основе DCCP – дублирование подтверждающей информации и дублирование порядковых номеров. Совместно они добавляют чуть больше 4 байтов на пакет по сравнению с использованием RTP на основе UDP и устранение избыточности не будет значительно сокращать издержки.

Рассмотрим сначала подтверждения. Оба протокола RTP и DCCP передают отправителю уведомления о скорости потери пакетов с помощью пакетов RTCP SR/RR15 и опций подтверждения DCCP. Эти механизмы обратной связи являются в некоторой степени избыточными. Однако пакеты RTCP SR/RR содержат информацию, которой нет в подтверждениях DCCP (например, interarrival jitter16), а подтверждения DCCP содержат информацию, отсутствующую в RTCP (например, ECN Nonce Echo). Ни один из механизмов обратной связи не заменяет полностью другой механизм.

Передача обоих типов информации не повышает значительно расходы по сравнению с передачей одного (любого) типа. Отчеты RTCP могут передаваться сравнительно редко (в среднем 1 раз в течение 5 сек. для узкополосных потоков). В DCCP некоторые механизмы обратной связи достаточно «дороги» (опции Ack Vector, например, передаются часто и содержат много данных), а другие сравнительно дешевы – подтверждения CCID 3 (TFRC) занимают 16 или 32 байта опций однократно в течение периода кругового обхода (более редкая передача отчетов снизит эффективность реакции механизма контроля насыщения на потери). Мы, следовательно, делаем вывод, что издержки на передачу подтверждений при использовании RTP на базе DCCP незначительно превышают издержки для случая RTP-over-UDP (по крайней мере, для CCID 3).

Одна явная избыточность может быть устранена на уровне приложения. Подробные уведомления о потере для каждого пакета, передаваемые в RTCP Extended Reports Loss RLE Block [RFC3611], могут быть получены из опций DCCP Ack Vector (обратное неверно, поскольку Loss RLE Block не содержит информации ECN). Поскольку реализациям DCCP следует обеспечивать API для доступа приложений к данным Ack Vector, приложения RTP на базе DCCP могут запрашивать опции DCCP Ack Vector или RTCP Extended Report Loss RLE Blocks, но не оба сразу.

Рассмотрим избыточность порядковых номеров в пакетах данных. Вложенный заголовок RTP содержит 16-битовый порядковый номер RTP. Большинство данных будет передаваться в пакетах DCCP-Data; пакеты DCCP-DataAck и DCCP-Ack обычно не требуются. Заголовок DCCP-Data имеет размер 12 байтов без учета опций и включает 24-битовый порядковый номер. Это на 4 байта превышает размер заголовка UDP. Любые опции пакета будут дополнительно увеличивать издержки, хотя многие механизмы CCID (например, CCID 3, TFRC) не требуют использования опций в большинстве пакетов данных.

Порядковый номер DCCP невозможно получить из порядкового номера RTP, поскольку в DCCP нумерация увеличивается для каждого пакета, независимо от наличия в нем данных приложения. Порядковый номер RTP также невозможно получить из номера DCCP [RFC3550]. Более того, удаление порядкового номера RTP не даст экономии пространства заголовка, поскольку в том используется выравнивание. Мы, следовательно, рекомендуем при передаче трафика RTP на базе транспорта DCCP использовать стандартные заголовки. 4 дополнительных байта заголовка являются вполне приемлемой платой за механизмы контроля насыщения DCCP и доступ к ECN. Конечным точкам, которым действительно требуется снижение размера заголовков, следует воспользоваться той или иной схемой компрессии заголовков.

17.2. Congestion Manager и мультиплексирование

Поскольку DCCP не обеспечивает гарантированной доставки с сохранением порядка, множество субпотоков приложения может мультиплексироваться в одно соединение DCCP без снижения производительности. Следовательно, для DCCP не требуется обеспечивать поддержку для множества субпотоков. В этом протокол отличается от SCTP [RFC2960].

Некоторые приложения могут захотеть совместно использовать данные о состоянии контроля насыщения для множества потоков DCCP с одинаковыми адресами отправителя и получателя. Функционально это может обеспечить Congestion Manager [RFC3124] – базовый элемент мультиплексирования. Однако CM не будет полностью поддерживать DCCP без внесения изменений – например, он не может достаточно элегантно обслуживать множество механизмов контроля насыщения.

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

DCCP не обеспечивает криптографической защиты. Приложениям, которым требуются криптографические методы защиты (целостность, аутентификация, конфиденциальность, контроль доступа и защита от повторного использования пакетов), следует применять IPsec или сквозные средства защиты иного типа; одним из таких вариантов может служить протокол Secure RTP [RFC3711].

Тем не менее, протокол DCCP подразумевает защиту от некоторых классов атак – атакующие не могут захватить соединение (неожиданно разорвать соединение или вынудить конечную точку принять данные атакующего взамен подлинной информации) без точного подбора порядковых номеров. Таким образом, при качественном выборе конечной точкой начального порядкового номера, атакующий DCCP должен сунуть свой нос в пакет данных для получения какой-либо вероятности успеха. Проверка корректности порядковых номеров обеспечивает надежные гарантии. В параграфе 7.5.5 подробно рассматривается вопрос защиты порядковых номеров. Это средство защиты требует лишь выбора случайных чисел для DCCP в соответствии с рекомендациями [RFC4086].

DCCP также обеспечивает механизмы ограничения возможных последствий некоторых атак на отказ служб. Эти механизмы включают опции Init Cookie (параграф 8.1.4), пакеты DCCP-CloseReq (параграф 5.5), код отбрасывания Application Not Listening (параграф 11.7.2), ограничения на обработку опций, способных приводить к сбросу соединения (параграф 7.5.5), ограничения на обработку некоторых сообщений ICMP (параграф 14.1) и различные ограничения скорости, которые позволяют серверам избавиться от избыточных вычислений или генерации ненужных пакетов (параграфы 7.5.3, 8.1.3 и др.).

DCCP не обеспечивает защиты от атакующих, способных просматривать пакеты данных.

18.1. Вопросы безопасности для неполных контрольных сумм

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

Когда пакеты DCCP содержат отличное от 0 значение поля Checksum Coverage, не учитываемая в контрольной сумме часть пакета может быть изменена в пути. Это вступает в противоречие с базовой идеей большинства механизмов аутентификации – считать аутентификацию успешной, если пакет не был изменен при передаче. До тех пор, пока не будет механизма аутентификации, способного работать только с частью пакета, аутентификация всегда будет давать сбои для пакетов DCCP с неполной контрольной суммой, если неучтенная в контрольной сумме часть пакета будет повреждена.

Проверка целостности IPsec (Encapsulation Security Protocol – ESP или Authentication Header – AH) применяется (как минимум) ко всем данным пакета IP. Повреждение любого бита данных будет приводить к отбрасыванию получателем IPsec пакета DCCP целиком, даже если повреждение связано с не учитываемой в контрольной сумме частью данных приложения DCCP.

Когда IPsec используется с шифрованием ESP для данных, канал не способен определить конкретный транспортный протокол пересылаемого пакета путем просмотра данных IP. В этом случае канал должен обеспечить стандартную проверку целостности, которая применяется ко всему пакету IP и содержащимся в нем данным. Неполные контрольные суммы DCCP в этом случае не дают никаких преимуществ.

Допускается использование шифрования (например, на транспортном или прикладном уровне). Отметим, что отказ от проверки целостности может в некоторых условиях приводить к риску потери конфиденциальности [B98].

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

19. Согласование с IANA

Агентство IANA выделило для протокола DCCP значение IP Protocol Number = 33.

DCCP вводит восемь наборов чисел, значения которых должны распределяться IANA. Мы указываем правила распределения (такие, как Standards Action), описанные в [RFC2434], и большинство реестров резервирует часть значений для экспериментов и тестирования [RFC3692]. Кроме того, DCCP требует создания реестра IANA Port Numbers для регистрации портов DCCP (см. параграф 19.9). IANA может без ограничений обращаться к DCCP Expert Reviewer с вопросами по любым реестрам, независимо от принятой для них политики распределения для получения разъяснений или при возникновении проблем с распределением.

19.1. Реестр типов пакетов

Каждая запись в реестре DCCP Packet Types содержит типа пакета (целое число от 0 до 15), имя типа (например, DCCP-Request) и ссылку на RFC, в котором определен данный тип. Изначально реестр заполняется значениями из таблицы 1 (параграф 5.1). Данный документ определяет типы 0 – 9, а тип 14 резервируется для экспериментов и тестирования.

Типы пакетов 10 – 13 и 15 в настоящее время являются резервными. Распределение этих значений должно осуществляться на основе процедуры Standards Action, которая требует просмотра и одобрения IESG, а также публикации RFC со статусом standards-track.

19.2. Реестр кодов сброса

Каждая запись в реестре DCCP Reset Codes содержит код сброса (Reset Code), задаваемый целым числом от 0 до 255, краткое описание кода (например, No Connection) и ссылку на RFC, где определяется Reset Code. Изначально реестр заполняется значениями из таблицы 2 (параграф 5.6). Данный документ определяет коды 0 – 11 и резервирует коды 120 – 126 для экспериментов и тестирования. Коды 12 – 119 и 127 в настоящее время являются резервными. Их следует распределять на основе процедуры IETF Consensus, требующей публикации RFC (статус standards track не требуется) с просмотром и одобрением IESG. Коды 128 – 255 резервируются для связанных с CCID реестров; каждый документ CCID Profile описывает управление соответствующим реестром.

19.3. Реестр типов опций

Каждая запись реестра опций DCCP содержит тип опции (целое число от 0 до 255), имя опции (например, Slow Receiver) и ссылку на RFC, где определен тип опции. Реестр изначально заполняется значениями из таблицы 3 (параграф 5.8). данный документ выделяет для типов опций значения 0 – 2 и 32 – 44, а опции типов 31 и 120 – 126 для экспериментов и тестирования. Опции типов 3 – 30, 45 – 119 и 127 в настоящее время зарезервированы. Их следует распределять на основе процедуры IETF Consensus, требующей публикации RFC (статус standards track не требуется) с просмотром и одобрением IESG. Опции типов 128 – 255 резервируются для связанных с CCID реестров; каждый документ CCID Profile описывает управление соответствующим реестром.

19.4. Реестр номеров признаков

Каждая запись в реестре признаков DCCP содержит номер признака (целое число от 0 до 255), его имя (например, ECN Incapable) и ссылку на RFC, где определяется признак. Реестр изначально заполняется значениями из таблицы 4 (параграф 6). Данный документ выделяет значения для признаков с номерами 0 – 9, а признаки 120 – 126 резервируются для экспериментов и тестирования. Признаки с номерами 10-119 и 127 являются резервными. Их следует распределять на основе процедуры IETF Consensus, требующей публикации RFC (статус standards track не требуется) с просмотром и одобрением IESG. Признаки с номерами 128 – 255 резервируются для связанных с CCID реестров; каждый документ CCID Profile описывает управление соответствующим реестром.

19.5. Реестр идентификаторов контроля насыщения

Каждая запись в реестре идентификаторов DCCP CCID содержит значение CCID (целое число от 0 до 255) имя механизма CCID (например, TCP-like Congestion Control) и ссылку на RFC, где определяется CCID. Реестр изначально заполняется значениями из таблицы 5 (глава 10). Значения CCID 2 и 3 выделены для опубликованных к настоящему моменту профилей, а значения 248 – 254 резервируются для экспериментов и тестирования. Значения CCID 0, 1, 4 – 247 и 255 в настоящее время являются резервными. Их следует распределять на основе процедуры IETF Consensus, требующей публикации RFC (статус standards track не требуется) с просмотром и одобрением IESG.

19.6. Реестр состояний Ack Vector

Каждая запись реестра DCCP Ack Vector States содержит Ack Vector State (целое число от 0 до 3), имя состояния (например, Received ECN Marked) и ссылку на RFC, где определяется состояние. Реестр изначально заполняется значениями из таблицы 6 (параграф 11.4). Данный документ определяет состояния 0, 1 и 3. Состояние с кодом 2 в настоящее время является резервным и должно распределяться на основании процедуры Standards Action, требующей просмотра и одобрения IESG, а также публикации RFC со статусом standards-track.

19.7. Реестр значений Drop Code

Каждая запись реестра DCCP Drop Codes содержит значение Data Dropped Drop Code 9целое число от 0 до 7) название Drop Code (например, Application Not Listening) и ссылку на RFC, где определяется Drop Code. Реестр изначально заполняется значениями из таблицы 7 (параграф 11.7). данный документ выделяет значения Drop Code 0 – 3 и 7. Коды 4 – 6 в настоящее время зарезервированы. Их следует распределять на основе процедуры Standards Action, требующей просмотра и одобрения IESG, а также публикации RFC со статусом standards-track.

19.8. Реестр кодов сервиса

Каждая запись в реестре Service Codes содержит значение Service Code (целое число от 0 до 4294967294); краткое описание сервиса на английском языке и может также включать ссылку на RFC или иной доступный документ, определяющий Service Code. В реестре следует указывать десятичное представление значений Service Code. Когда код может быть представлен в формате «SC:», согласно правилам параграфа 8.1.2, в реестре следует также указывать соответствующее представление в коде ASCII без префикса «SC:». Таким образом, число 1717858426 будет дополнительно представляться строкой «fdpz». Значения кодов сервиса не связаны исключительно с протоколом DCCP. Значение Service Code 0 зарезервировано (оно представляет отсутствие значимого кода сервиса), а значения 1056964608 – 1073741823 (старший байт соответствует символу ASCII «?») зарезервированы для приватного использования. Отметим, что значение 4294967295 не является корректным кодом сервиса. Большая часть оставшихся значений Service Code распределяется в порядке получения запросов (процедура First Come First Served), без обязательной публикации RFC; исключения перечислены в параграфе 8.1.2. данный документ выделяет одно значение Service Code 1145656131 (DISC). Это значение соответствует сервису discard, которые отбрасывает все полученные данные и ничего не передает в ответ.

19.9. Реестр номеров портов

Службы DCCP могут использовать контактные номера портов для предоставления услуг неизвестным абонентам, как это делается в TCP и UDP. Агентству IANA, следовательно, нужно открыть реестр номеров портов для DCCP, используя приведенные ниже правила, которые мы разработали с учетом существующих процедур регистрации номеров портов.

Номера портов делятся на три группы. Общеизвестные порты имеют номера от 0 до 1023, зарегистрированные порты – от 1024 до 49151, а динамически выделяемые и предназначенные для приватного использования – от 49152 до 65535. Общеизвестные и зарегистрированные номера портов предназначены для использования серверными приложениями, которым нужен принятый по умолчанию номер порта. В большинстве систем общеизвестные номера портов могут использоваться только системными (или принадлежащими пользователю root) процессами или программами, запущенными от имени привилегированных пользователей, а зарегистрированные номера могут применяться обычными пользовательскими процессами и программами, запущенными от имени непривилегированных пользователей. Порты Dynamic и Private предназначены для временного использования, включая порты на клиентской стороне соединений, портов согласуемых независимо от соединения и тестирования приложений до регистрации для них выделенного порта. Следовательно, номера таких портов недопустимо регистрировать.

Для регистрации в реестре Port Numbers портов DCCP следует принимать номера из диапазонов Well Known и Registered. Порты Well Known и Registered Ports не следует использовать без регистрации. Хотя в некоторых случаях (например, при переносе UDP-приложений на DCCP) представляется естественным начать использование порта DCCP до завершения регистрации, мы подчеркиваем, что IANA не гарантирует регистрацию конкретного запрошенного значения для портов Well Known и Registered. Регистрацию номера порта следует запрашивать как можно раньше.

При каждой регистрации порта нужно указывать следующие данные:

  • Краткое имя порта, содержащее только буквы латиницы (A-Z и a-z), цифры (0-9) и символы «-_+./*» (не включая кавычек).
  • Номер порта, для которого запрашивается регистрация.
  • Краткое описание назначения порта на английском языке. Это описание должно включать один или несколько разделенных пробелами текстовых дескрипторов Service Code, именующих порт с соответствующим значением Service Code (см. параграф 8.1.2).
  • Имя и контактная информация персоны или организации, регистрирующей номер порта. По возможности следует указать также ссылку на документ, определяющий использование порта. Если регистрацией занимается рабочая группа IETF, достаточно указать название группы, но рекомендуется включать и контактную информацию.

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

  • Конкретное имя не следует регистрировать более, чем для одного порта DCCP.
  • Имя порта, зарегистрированное для UDP может быть зарегистрировано и для DCCP. При такой регистрации следует использовать такой же номер порта, который зарегистрирован для данного имени в UDP.
  • Перед регистрацией порта следует определить его конкретное назначение. Например, зарегистрированные порты UDP не следует бесцельно переносить в регистрацию портов для DCCP.
  • Имена портов, связанные обычно с TCP и/или SCTP, не следует регистрировать для DCCP, поскольку имя такого порта косвенно предполагает транспорт с гарантированной доставкой. Например, мы рекомендуем не регистрировать порта с именем http для протокола DCCP. Однако, если подобная регистрация имеет смысл (т. е., имеется конкретное назначение для данного порта), при регистрации порта DCCP следует использовать тот же номер, который уже зарегистрирован для другого протокола.
  • Допускается множественная регистрация для одного номера порта DCCP, если значения Service Code не совпадают.

Этот документ регистрирует один порт (в качестве модели регистрации).

   discard    9/dccp    Discard SC:DISC
   # IETF dccp WG, Eddie Kohler <kohler@cs.ucla.edu>, [RFC4340]

Сервис discard, который принимает соединения DCCP через порт 9, отбрасывает все полученные данные приложения и не передает никаких данных в ответ. Таким образом, порт discard в DCCP аналогичен порту TCP discard и может служить для проверки работоспособности стека DCCP.

20. Благодарности

Благодарим Jitendra Padhye за его помощь при подготовке ранних версий этой спецификации.

Спасибо Junwen Lai и Arun Venkataramani, которые, в качестве интернов ICIR, создавали прототип реализации DCCP. В частности, по рекомендации Junwen Lai старый механизм согласования признаков был забракован и заменен заново созданным механизмом. Отклики Arun Venkataramani позволили улучшить Приложение A.

Благодарим сотрудников и интернов ICIR и бывшего ACIRI, а также членов рабочих групп End-to-End Research и Transport Area за их отклики по DCCP. Особая благодарность просматривавшим документ экспертам – Greg Minshall, Eric Rescorla и Magnus Westerlund – за подробные комментарии и найденные проблемы, а также Rob Austein и Steve Bellovin за письменные и устные комментарии. Отдельно благодарим Aaron Falk, который руководил рабочей группой в процессе разработки спецификации.

Мы также благодарим тех, кто внес свои комментарии и предложения через DCCP BOF, рабочую группу и почтовые конференции, включая Damon Lanphear, Patrick McManus, Colin Perkins, Sara Karlberg, Kevin Lai, Bernard Aboba, Youngsoo Choi, Pengfei Di, Dan Duchamp, Lars Eggert, Gorry Fairhurst, Derek Fawcus, David Timothy Fleeman, John Loughney, Ghyslain Pelletier, Hagen Paul Pfeifer, Tom Phelan, Stanislav Shalunov, Somsak Vanit-Anunchai, David Vos, Yufei Wang и Michael Welzl. В частности отметим многочисленные подробные отклики Colin Perkins, предложенную Michael Welzl опцию Data Checksum, отклики Gorry Fairhurst во вопросам контрольных сумм, а также модель Colored Petri Net [VBK05], предложенную Somsak Vanit-Anunchai, Jonathan Billington и Tul Kongprakaiwoot и позволившую обнаружить некоторые проблемы при обмене сообщениями.

Приложение A. Реализация Ack Vector

В этом приложении обсуждаются детали обработки подтверждений DCCP в контексте абстрактной реализации Ack Vector. Приложение является информативным, а не нормативным.

Первая часть нашей реализации работает на стороне HC-Receiver и, следовательно, подтверждает пакеты данных. Эта часть генерирует опции Ack Vector. Реализация имеет следующие характеристики:

  • не более 1 байта состояния на пакет подтверждения;
  • время O(1) затрачивается на обновление состояния при доставке нового пакета (нормальная ситуация);
  • кумулятивные подтверждения;
  • быстрое удаление старого состояния.

Базовая структура данных представляет собой кольцевой буфер, содержащий информацию о подтвержденных пакетах. Каждый байт этого буфера содержит состояние и групповой код (run length); состояние может принимать значения 0 (пакет получен), 1 (пакет имеет маркер ECN) или 3 (пакет еще не получен). Начало буфера находится слева. Реализация поддерживает 5 переменных в дополнение к содержимому буфера:

  • переменные buf_head и buf_tail показывают активную часть буфера;
  • buf_ackno содержит значение Acknowledgement Number самого свежего подтвержденного пакета в буфере; этой переменной соответствует указатель head;
  • buf_nonce представляет собой однобитовую сумму (четность или «Исключающее ИЛИ») значений ECN Nonce, полученных во всех пакетах, подтверждаемых буфером со статусом State 0.

Вид буфера подтверждений показан на рисунке.

+---------------------------------------------------------------+
|S,L|S,L|S,L|S,L|   |   |   |   |S,L|S,L|S,L|S,L|S,L|S,L|S,L|S,L|
+---------------------------------------------------------------+
              ^                   ^
           buf_tail     buf_head, buf_ackno = A     buf_nonce = E

  <=== buf_head и buf_tail перемещаются в этом направлении <===

Каждая пара «S,L» представляет байт State/Run length. Мы будем показывать только активную часть кольцевого буфера и добавлять комментарии, показывающие Acknowledgement Number для последнего активного байта в буфере. Пример показан ниже.

  +-----------------------------------------------+
A |S,L|S,L|S,L|S,L|S,L|S,L|S,L|S,L|S,L|S,L|S,L|S,L| T    BN[E]
  +-----------------------------------------------+

Здесь переменная buf_nonce имеет значение E, а buf_ackno = A. Будем использовать этот буфер в качестве рабочего примера.

         +---------------------------+
      10 |0,0|3,0|3,0|3,0|0,4|1,0|0,0| 0    BN[1]   [Example Buffer]
         +---------------------------+

Словами содержимое буфера можно описать так:

пакет 10 был получен (начало буфера имеет порядковый номер 10, состояние 0 и run length 0);

пакеты 9, 8 и 7 еще не получены (три следующих байта показывают состояние 3 и run length 0.)4

пакеты 6, 5, 4, 3 и 2 были получены;

пакет 1 имеет маркер ECN;

пакет 0 был получен.

Однобитовая сумма значений ECN Nonce для пакетов 10, 6, 5, 4, 3, 2 и 0 равна 1.

Кроме того HC-Receiver нужно сохранять некоторые данные о недавно переданных значениях Ack Vector. Для этого каждый пакет, содержащий Ack Vector, запоминается в 4 переменных:

  • ack_seqno содержит значение Sequence Number, использованное для пакета; это порядковый номер HC-Receiver;
  • ack_ptr – значение buf_head в момент подтверждения;
  • ack_runlen – групповой код, находящийся в байте буфера данных с позицией buf_head в момент подтверждения;
  • ack_ackno – значение Acknowledgement Number, использованное для пакета; это порядковый номер HC-Sender; поскольку подтверждения являются кумулятивными, один номер полностью задает всю информацию о пакете, подтверждаемом данным значением Ack Vector;
  • ack_nonce – 1-битовая сумма ECN Nonce для всех пакетов со State 0 в буфере между позициями buf_head и ack_ackno, включительно; изначально эта переменная равна значению Nonce Echo в Ack Vector подтверждения (или, если пакет подтверждения содержит несколько опций Ack Vector, «исключающее ИЛИ» для всех Ack Vector); значение переменной меняется по мере удаления данных о старых подтверждениях (сближение ack_ptr и buf_head) и прибытия старых пакетов (смена State 3 или State 1 на State 0).

A.1. Получение пакетов

В этом параграфе рассматривается, как HC-Receiver обновляет буфер подтверждений по мере доставки пакетов от HC-Sender.

A.1.1. Новые пакеты

Когда прибывает пакет с Sequence Number > buf_ackno, HC-Receiver обновляет buf_head (перемещая соответствующим образом влево), buf_ackno (сюда помещается значение Sequence Number из нового пакета), и, возможно, buf_nonce (в зависимости от ECN Nonce в принятом пакете) в дополнение к обновлению самого буфера. Например, если пакет 11 от HC-Sender прибыл с маркером ECN, показанный выше Example Buffer будет переходить в состояние, показанное на рисунке справа (изменения отмечены звездочками).

         ** +***----------------------------+
         11 |1,0|0,0|3,0|3,0|3,0|0,4|1,0|0,0| 0    BN[1]
         ** +***----------------------------+

Если состояние пакета совпадает с состоянием в голове буфера, HC-Receiver может увеличить значение run length (вплоть до максимального). Например, если пакет 11 от HC-Sender прибудет без маркера ECN и со значением ECN Nonce 0, Example Buffer может перейти в состояние, показанное на рисунке слева.

             ** +--*------------------------+
             11 |0,1|3,0|3,0|3,0|0,4|1,0|0,0| 0    BN[1]
             ** +--*------------------------+

Порядковый номер вновь прибывшего пакета может, естественно, не совпасть с ожидаемым номером. В таких случаях HC-Receiver будет вводить для пропущенных пакетов состояние State 3. Если отсутствует несколько пакетов, HC-Receiver можно ввести множество байтов с run length = 0 или один байт с соответствующим значением группового кода. Использование отдельного байта для каждого пропущенного пакета упрощает обновление при поступлении какого-либо из пропущенных пакетов. Например, если пакет 12 от HC-Sender прибудет с ECN Nonce 1, Example Buffer перейдет в состояние, показанное на рисунке справа.

      ** +*******----------------------------+         *
      12 |0,0|3,0|0,1|3,0|3,0|3,0|0,4|1,0|0,0| 0    BN[0]
      ** +*******----------------------------+         *

Кольцевой буфер может переполняться, когда HC-Sender передает данные с очень высокой скоростью, а подтверждения от HC-Receiver не успевают доходить до HC-Sender или тот забывает подтверждать эти подтверждения (в результате HC-Receiver не может сбросить старые состояния). В этом случае полусоединению HC-Receiver следует сжать буфер (увеличивая, по возможности, значения run length), переместить состояния в буфер большего размера или, в качестве крайней меры, отбрасывать все принятые пакеты без их обработки, пока буфер не освободится.

A.1.2. Старые пакеты

Когда прибывает пакет с Sequence Number S <= buf_ackno, HC-Receiver будет просматривать таблицу в поисках байта, соответствующего S (структуры с индексированием могут упростить такой поиск). Если номер S ранее считался потерянным (State 3) и указан в байте с run length 0, HC-Receiver может просто изменить состояние для этого байта. Например, если пакет в от HC-Sender поступил с ECN Nonce 0, Example Buffer будет иметь вид, показанный на рисунке справа.

               +--------*------------------+
            10 |0,0|3,0|0,0|3,0|0,4|1,0|0,0| 0    BN[1]
               +--------*------------------+

Если пакет S не был указан среди потерянных или отсутствует в таблице, пакет возможно является возникшим в сети дубликатом и его следует игнорировать (состояние маркера ECN для нового пакета может отличаться от состояния, указанного в буфере; описание таких ситуаций приведено в параграфе 11.4.1). Если для номера S в буфере используется группа с отличным от нуля значением run length, может потребоваться перераспределение буфера с целью освобождения места для одного или двух байтов.

Могут также потребоваться операции с полями ack_nonce при доставке старого пакета. В частности, когда S переходит из состояния 3 или 1 в состояние 0 и S имеет ECN Nonce 1, реализации следует изменить значение битов ack_nonce для всех подтверждений с ack_ackno >= S.

При использовании описанной структуры данных невозможна смена состояния 0 на состояние 1, поскольку буфер не сохраняет отдельных значений ECN Nonce.

A.2. Отправка подтверждений

Когда получателю HC-Receiver нужно генерировать подтверждение, содержимое буфера можно просто скопировать в одну или несколько опций Ack Vector. Копирование Ack Vector может не обеспечивать максимального сжатия. Например, показанный выше Example Buffer содержит три байта 3,0 подряд, которые можно объединить в один байт 3,2. HC-Receiver может, следовательно, выполнять сжатие буфера перед копированием или в процессе копирования.

В каждое подтверждение, передаваемое получателем HC-Receiver следует включать все состояния из буфера. Таким образом, подтверждения являются кумулятивными.

Если подтверждение помещается в одну опцию Ack Vector, значение Nonce Echo этой опции просто будет равно buf_nonce. Для множества опций Ack Vector требуется больше операций. Значения Ack Vector следует расщепить в точках, соответствующих предыдущим подтверждениям, поскольку сохраненные поля ack_nonce обеспечивают достаточно информации для расчета корректных значений Nonce Echo. Реализации следует, подтверждать данные по крайней мере один раз на 253 байта буферного пространства (иначе не будет возможности расчета Nonce Echo).

Для каждого передаваемого подтверждения HC-Receiver будет добавлять новую запись. Значение ack_seqno будет равно порядковому номеру HC-Receiver, использованному для пакета подтверждения; ack_ptr = buf_head; значение ack_runlen будет равно значению run length из байта buf_head; ack_ackno = buf_ackno; ack_nonce will = buf_nonce.

A.3. Очистка состояния

Некоторые из пакетов от HC-Sender будут включать номера подтверждений, которые подтверждают подтверждения HC-Receiver. При получении такого подтверждения HC-Receiver находит запись R с соответствующим значением ack_seqno и выполняет следующие операции:

  • если значение run length в байте R.ack_ptr byte превышает R.ack_runlen, значение run length уменьшается на R.ack_runlen + 1 и устанавливается buf_tail = R.ack_ptr; иначе устанавливается buf_tail = R.ack_ptr + 1;
  • если R.ack_nonce = 1, меняется значение бита buf_nonce и ack_nonce для всех последующих записей о подтверждениях;
  • удаляется запись R и все предшествующие ей записи.

(HC-Receiver может сохранять часть старой информации на случай получения пакетов, считавшихся потерянными). Предположим, что получатель HC-Receiver, сохраняющий Example Buffer, уже передал 2 подтверждения:

  1. ack_seqno = 59, ack_runlen = 1, ack_ackno = 3, ack_nonce = 1.
  2. ack_seqno = 60, ack_runlen = 0, ack_ackno = 10, ack_nonce = 0.

Далее предположим, что HC-Receiver получает от HC-Sender пакет DCCP-DataAck с Acknowledgement Number 59. Этот пакет говорит получателю HC-Receiver, что отправитель HC-Sender принял и обработал всю информацию из пакета от HC-Receiver с номером 59. Этот пакет подтверждает полученный от HC-Sender пакет 3 и HC-Sender имеет от HC-Receiver подтверждения для пакетов 0, 1, 2 и 3. Вид буфера Example Buffer показан на рисунке.

               +------------------*+ *       *
            10 |0,0|3,0|3,0|3,0|0,2| 4    BN[0]
               +------------------*+ *       *

Значение run length для «хвостового» байта было изменено, поскольку пакет 3 был учтен в этом байте. Поскольку значение R.ack_nonce было равно 1, значение бита buf_nonce изменяется, как и значения битов ack_nonce для последующих подтверждений (в данном случае запись HC-Receiver Ack 60 не показана; для нее значение ack_nonce меняется на 1). HC-Receiver может также удалить сохраненную информацию для HC-Receiver Ack 59 и всех предшествующих подтверждений.

Осторожная реализация может предпринять попытку обеспечения разумной устойчивости к смене порядка доставки. Воспользуемся снова примером Example Buffer, предположив, что пакет 9 приходит с нарушениям порядка доставки. Вид буфера для этого случая показан на рисунке.

                +----*----------------------+
             10 |0,0|0,0|3,0|3,0|0,4|1,0|0,0| 0     BN[1]
                +----*----------------------+

Опасность заключается в том, что HC-Sender может подтвердить предыдущее подтверждение от HC-Receiver (номер 60), которое говорит о том, что пакет 9 не был получен, до того, как HC-Receiver получит шанс на передачу нового подтверждения, указывающего получение пакета 9. Следовательно, по получении пакета 9 HC-Receiver может изменить подтверждающую запись, как показано ниже:

  1. ack_seqno = 59, ack_ackno = 3, ack_nonce = 1.
  2. ack_seqno = 60, ack_ackno = 3, ack_nonce = 1.

Т. е., пакет Ack 60 сейчас трактуется подобно дубликату пакета Ack 59. Это будет предотвращать перемещение хвоста буфера за пакет 9, пока HC-Receiver не узнает, что полусоединение HC-Sender увидело вектор Ack Vector, показывающий доставку пакета.

A.4. Обработка подтверждений

При получении подтверждения HC-Sender в общем случае следует внимательно относится к номерам пакетов, которые были отброшены и/или помечены маркером ECN. Эта информация считывается из опций Ack Vector. Кроме того, следует проверить корректность ECN Nonce (как было сказано в параграфе 11.4.1, может возникнуть потребность в сохранении более детальной информации о подтвержденных пакетах на случай смены состояния пакетов между подтверждениями или получения запроса о доставке пакета от прикладной программы).

HC-Sender может также подтверждать подтверждения от HC-Receiver для удаления старых состояний Ack Vector (поскольку подтверждения Ack Vector доставляются гарантированно, получатель HC-Receiver должен поддерживать информацию Ack Vector и повторно передавать ее, пока не будет уверенности, что она получена HC-Sender). Достаточно использования простого алгоритма – поскольку подтверждения Ack Vector являются кумулятивными, один номер подтверждения говорит HC-Receiver, как много подтверждающих данных было получено. В предположении что HC-Receiver не передает данных, полусоединение HC-Sender может гарантировать, что по крайней мере 1 раз за период кругового обхода оно будет передавать пакет DCCP-DataAck, подтверждающий прием последнего пакета DCCP-Ack. Естественно, что полусоединению HC-Sender требуется подтверждать подтверждения от HC-Receiver только в том случае, когда HC-Sender передает также данные. Если HC-Sender не передает данных, состояние Ack Vector для HC-Receiver будет неизменным и не возникает необходимости в его сжатии. Отправитель HC-Sender должен отслеживать отбрасывание и маркировку ECN в полученных пакетах DCCP-Ack, чтобы можно было корректировать скорость передачи (например, с помощью Ack Ratio) подтверждений от HC-Receiver в случаях возникновения перегрузок.

Если другое полусоединение не является статичным (т. е., HC-Receiver передает данные в направлении HC-Sender, возможно используя другой механизм CCID), подтверждений в этом полусоединении достаточно будет для очистки состояния HC-Receiver.

Приложение B. Обоснование применения неполных контрольных сумм

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

Многие из приложений, которые предполагается реализовать на основе DCCP, обеспечивают устойчивость к некоторому уровню потери данных или используют транспорт с гарантированной доставкой. Некоторые из этих приложений (например, аудио) устойчивы также к повреждению данных. Такие устойчивые к ошибкам приложения предпочтут получить от DCCP поврежденные пакеты, нежели эти пакеты будут просто отбрасываться протоколом. Это связано отчасти с контролем насыщения – DCCP не может указать разницу между пакетами, отброшенными в результате повреждения и перегрузок, поэтому протокол должен снижать скорость передачи при любых потерях. Такое поведение может привести к снижению полосы соединения до неприемлемых значений. Для некоторых сетевых технологий повреждение данных не зависит от загрузки сети или, по крайней мере, не всегда коррелирует с уровнем насыщения. Следовательно, повреждение пакетов (если заголовок и опции DCCP не повреждены) не должно вызывать существенного снижения скорости передачи, которое может вызываться механизмом контроля насыщения.

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

Таким образом, с точки зрения приложений использование неполных контрольных сумм представляется привлекательным. Однако польза от применения неполных контрольных сумм будет будет зависеть от того, как частично поврежденные пакеты будут доставляться получателю. Если контрольные суммы канального уровня (CRC) всегда ведут к отбрасыванию поврежденных пакетов, польза от применения неполных контрольных сумм будет только для случаев повреждения пакетов в маршрутизаторах и иных местах, не контролируемых на основе CRC канального уровня. Не удалось прийти к согласию по оценке вероятности того, что новые сетевые технологии для каналов с высоким уровнем ошибок будут использовать строгую контрольную сумму CRC для всего пакета. DCCP может адаптировать приложения к использованию таких каналов, но сложно предсказать, насколько это будет актуально для будущих технологий канального уровня.

Кроме того, неполные контрольные суммы несовместимы с механизмами аутентификации на уровне IP (такими, как IPsec AH), которые используют криптографические хэш-функции для всего пакета. В результате, если требуется одновременно с неполными контрольными суммами обеспечивать криптографическую аутентификацию, последняя должна выполняться для данных приложения. Возможным вариантом будет появление протокола, подобного Secure RTP. Однако такая аутентификация на «прикладном уровне» не защищает согласование опций и машину состояний DCCP от обманных пакетов. Альтернативой может служить использование IPsec ESP и шифрование заголовков DCCP для защиты от атак с проверкой корректности заголовков DCCP для аутентификации источника пакета, содержащего заголовок (владелец корректного ключа). Такая схема защищает от повторного использования пакетов (благодаря порядковым номерам DCCP), она не обеспечивает достаточной защиты от некоторых MITM-атак17, поскольку данные пакета не связаны с его заголовком. Таким образом, аутентификация на уровне приложения может потребовать связи с IPsec ESP или иным механизмом, обеспечивающим комплексное защитное решение. Связанные с этим издержки могут оказаться неприемлемыми для некоторых приложений, которым подходят неполные контрольные суммы.

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

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

[RFC793] Postel, J., “Transmission Control Protocol”, STD 7, RFC 793, September 1981.

[RFC1191] Mogul, J. and S. Deering, “Path MTU discovery”, RFC 1191, November 1990.

[RFC2119] Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels”, BCP 14, RFC 2119, March 1997.

[RFC2434] Narten, T. and H. Alvestrand, “Guidelines for Writing an IANA Considerations Section in RFCs”, BCP 26, RFC 2434, October 1998.

[RFC2460] Deering, S. and R. Hinden, “Internet Protocol, Version 6 (IPv6) Specification”, RFC 2460, December 1998.

[RFC3168] Ramakrishnan, K., Floyd, S., and D. Black, “The Addition of Explicit Congestion Notification (ECN) to IP”, RFC 3168, September 2001.

[RFC3309] Stone, J., Stewart, R., and D. Otis, “Stream Control Transmission Protocol (SCTP) Checksum Change”, RFC 3309, September 2002.

[RFC3692] Narten, T., “Assigning Experimental and Testing Numbers Considered Useful”, BCP 82, RFC 3692, January 2004.

[RFC3775] Johnson, D., Perkins, C., and J. Arkko, “Mobility Support in IPv6”, RFC 3775, June 2004.

[RFC3828] Larzon, L-A., Degermark, M., Pink, S., Jonsson, L-E., and G. Fairhurst, “The Lightweight User Datagram Protocol (UDP-Lite)”, RFC 3828, July 2004.

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

[B98] Bellovin, S. M., “Cryptography and the Internet”, CRYPTO ’98 (LNCS 1462), pp 46-55, August 1988.

[BB01] Bellovin, S.M. and M. Blaze, “Cryptographic Modes of Operation for the Internet”, 2nd NIST Workshop on Modes of Operation, August 2001.

[M85] Morris, R. T., “A Weakness in the 4.2BSD Unix TCP/IP Software”, Computer Science Technical Report 11719, AT&T Bell Laboratories, Murray Hill, NJ, February 1985.

[PMTUD] Mathis, M. and J. Heffner, “Path MTU Discovery”, Work in Progress20, March 2006.

[RFC792] Postel, J., “Internet Control Message Protocol”, STD 5, RFC 792, September 1981.

[RFC1812] Baker, F., “Requirements for IP Version 4 Routers”, RFC 1812, June 1995.

[RFC1948] Bellovin, S., “Defending Against Sequence Number Attacks”, RFC 1948, May 1996.

[RFC1982] Elz, R. and R. Bush, “Serial Number Arithmetic”, RFC 1982, August 1996.

[RFC2018] Mathis, M., Mahdavi, J., Floyd, S., and A. Romanow, “TCP Selective Acknowledgement Options”, RFC 2018, October 1996.

[RFC2401] Kent, S. and R. Atkinson, “Security Architecture for the Internet Protocol”, RFC 240121, November 1998.

[RFC2463] Conta, A. and S. Deering, “Internet Control Message Protocol (ICMPv6) for the Internet Protocol Version 6 (IPv6) Specification”, RFC 2463, December 1998.

[RFC2581] Allman, M., Paxson, V., and W. Stevens, “TCP Congestion Control”, RFC 2581, April 1999.

[RFC2960] Stewart, R., Xie, Q., Morneault, K., Sharp, C., Schwarzbauer, H., Taylor, T., Rytina, I., Kalla, M., Zhang, L., and V. Paxson, “Stream Control Transmission Protocol”, RFC 2960, October 2000.

[RFC3124] Balakrishnan, H. and S. Seshan, “The Congestion Manager”, RFC 3124, June 2001.

[RFC3360] Floyd, S., “Inappropriate TCP Resets Considered Harmful”, BCP 60, RFC 3360, August 2002.

[RFC3448] Handley, M., Floyd, S., Padhye, J., and J. Widmer, “TCP Friendly Rate Control (TFRC): Protocol Specification”, RFC 3448, January 2003.

[RFC3540] Spring, N., Wetherall, D., and D. Ely, “Robust Explicit Congestion Notification (ECN) Signaling with Nonces”, RFC 3540, June 2003.

[RFC3550] Schulzrinne, H., Casner, S., Frederick, R., and V. Jacobson, “RTP: A Transport Protocol for Real-Time Applications”, STD 64, RFC 3550, July 2003.

[RFC3611] Friedman, T., Caceres, R., and A. Clark, “RTP Control Protocol Extended Reports (RTCP XR)”, RFC 3611, November 2003.

[RFC3711] Baugher, M., McGrew, D., Naslund, M., Carrara, E., and K. Norrman, “The Secure Real-time Transport Protocol (SRTP)”, RFC 3711, March 2004.

[RFC3819] Karn, P., Bormann, C., Fairhurst, G., Grossman, D., Ludwig, R., Mahdavi, J., Montenegro, G., Touch, J., and L. Wood, “Advice for Internet Subnetwork Designers”, BCP 89, RFC 3819, July 2004.

[RFC4086] Eastlake, D., 3rd, Schiller, J., and S. Crocker, “Randomness Requirements for Security”, BCP 106, RFC 4086, June 2005.

[RFC4341] Floyd, S. and E. Kohler, “Profile for Datagram Congestion Control Protocol (DCCP) Congestion Control ID 2: TCP-like Congestion Control”, RFC 4341, March 2006.

[RFC4342] Floyd, S., Kohler, E., and J. Padhye, “Profile for Datagram Congestion Control Protocol (DCCP) Congestion Control ID 3: TCP-Friendly Rate Control (TFRC)”, RFC 43421, March 2006.

[SHHP00] Spatscheck, O., Hansen, J.S., Hartman, J.H., and L.L. Peterson, “Optimizing TCP Forwarder Performance”, IEEE/ACM Transactions on Networking 8(2):146-157, April 2000.

[SYNCOOKIES] Bernstein, D.J., “SYN Cookies”26, http://cr.yp.to/syncookies.html (по состоянию на март 2006).

[VBK05] Vanit-Anunchai, S., Billington, J., and T. Kongprakaiwoot, “Discovering Chatter and Incompleteness in the Datagram Congestion Control Protocol”, FORTE 2005, pp 143-158, October 2005.

Адреса авторов

Eddie Kohler

4531C Boelter Hall

UCLA Computer Science Department

Los Angeles, CA 90095

USA

EMail: kohler@cs.ucla.edu

Mark Handley

Department of Computer Science

University College London

Gower Street

London WC1E 6BT

UK

EMail: M.Handley@cs.ucl.ac.uk

Sally Floyd

ICSI Center for Internet Research

1947 Center Street, Suite 600

Berkeley, CA 94704

USA

EMail: floyd@icir.org


Перевод на русский язык

Николай Малых

nmalykh@protocols.ru

Полное заявление авторских прав

Copyright (C) The Internet Society (2006).

This document is subject to the rights, licenses and restrictions contained in BCP 78, and except as set forth therein, the authors retain all their rights.

This document and the information contained herein are provided on an “AS IS” basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

Интеллектуальная собственность

The IETF takes no position regarding the validity or scope of any Intellectual Property Rights or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; nor does it represent that it has made any independent effort to identify any such rights. Information on the procedures with respect to rights in RFC documents can be found in BCP 78 and BCP 79.

Copies of IPR disclosures made to the IETF Secretariat and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementers or users of this specification can be obtained from the IETF on-line IPR repository at http://www.ietf.org/ipr.

The IETF invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights that may cover technology that may be required to implement this standard. Please address the information to the IETF at ietf-ipr@ietf.org.

Подтверждение

Финансирование функций RFC Editor обеспечено IETF Administrative Support Activity (IASA).


1Процедура «First Come First Served».

2Требуется спецификация.

3Additive Increase – аддитивное увеличение, Multiplicative Decrease – мультипликативное уменьшение.

4TCP-Friendly Rate Control – дружественное к TCP управление скоростью.

5В оригинале «piggybacking». Прим. перев.

6Drop Code – код отбрасывания.

7Протокольные ограничения.

8Приложение не прослушивает входящие данные.

9Maximum packet size.

10Congestion Control Maximum packet size.

11Path Maximum Transmission Unit – максимальный размер передаваемого блока для пути через сеть.

12Don’t Fragment – не фрагментировать.

13Расширение недоступно.

14Real-Time Transport Protocol — транспортный протокол для приложений, работающих в реальном масштабе времени. Прим. перев.

15RTP Control Protocol Sender/Receiver Report.

16Флуктуации интервала доставки пакетов.

17man-in-the-middle attack – атака основанная на перехвате пакетов с участием человека. Прим. перев.

19Копию статьи можно найти на сайте pdos.csail.mit.edu/~rtm/papers/117.pdf, а перевод доступен на сайте www.protocols.ru. Прим. перев.

20Работа завершена и опубликована в RFC 4821. Прим. перев.

21Этот документ признан устаревшим и заменен RFC 4301. Прим. перев.

22Этот документ признан устаревшим и заменен RFC 5681. Прим. перев.

23Этот документ признан устаревшим и заменен RFC 4960. Прим. перев.

24Этот документ признан устаревшим и заменен RFC 5348. Прим. перев.

26Перевод этой статьи имеется на сайте www.protocols.ru. Прим. перев.

Запись опубликована в рубрике RFC. Добавьте в закладки постоянную ссылку.

Добавить комментарий

Or