RFC 9000 QUIC: A UDP-Based Multiplexed and Secure Transport (часть 2)

image_print

Часть 1

13. Пакетизация и надёжность доставки

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

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

Одним из преимуществ QUIC является предотвращение блокировки head-of-line между разными потоками. При наличии потерь пакетов блокируются лишь потоки с данными из потерянного пакета в ожидании повторной передачи, а другие потоки продолжают работать нормально. Отметим, что при включении данных из нескольких потоков в один пакет QUIC потеря такого пакета блокирует обработку всех этих потоков. Разработчикам рекомендуется включать в исходящие пакеты минимальное число потоков без потери эффективности в результате передачи мелких пакетов.

13.1. Обработка пакета

Пакет недопустимо подтверждать до снятия защиты и обработки всех содержащихся в нем кадров. Для кадров STREAM это означает, что данные помещены в очередь для отправки протоколу приложения, но не требуется их фактическая доставка и потребление.

После полной обработки пакета получатель подтверждает приём отправкой одного или нескольких кадров ACK с номером полученного пакета.

Конечной точке следует считать подтверждение пакета, который она не передавала, ошибкой соединения типа PROTOCOL_VIOLATION, если она может это обнаружить. Дополнительное обсуждение приведено в параграфе 21.4.

13.2. Генерация подтверждений

Конечные точки подтверждают все пакеты, которые они получили и обработали. Однако лишь пакеты с запросом подтверждения (ack-eliciting) вызывают отправку кадра ACK в интервале максимально разрешённой задержки подтверждения. Остальные пакеты подтверждаются лишь при отправке кадра ACK по иным причинам.

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

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

13.2.1. Передача кадров ACK

Каждый пакет следует подтверждать по меньшей мере один раз, а пакеты с запросом подтверждения должны подтверждаться не менее 1 раза в интервале максимальной задержки, указанного конечной точкой в транспортном параметре max_ack_delay (см. раздел 18.2). Параметр max_ack_delay задаёт явное требование – конечная точка обещает никогда не задерживать преднамеренно подтверждения пакетов ack-eliciting более указанного времени. Если задержка происходит, любое превышение учитывается при оценке RTT и может приводить к ложным или задержанным повторам передачи партнёром. Отправитель использует значение max_ack_delay, заданное получателем, при определении тайм-аутов для повтора по времени, как описано в параграфе 6.2 [QUIC-RECOVERY].

Конечная точка должна подтверждать все пакеты Initial и Handshake с запросом подтверждения незамедлительно, а все пакеты 0-RTT и 1-RTT с запросом подтверждения в анонсированном интервале max_ack_delay, с одним исключением. До подтверждения согласования (handshake) у конечной точки может не быть ключей для расшифровки принимаемых пакетов Handshake, 0-RTT, 1-RTT, поэтому она может буферизовать их и подтверждать после обретения ключей.

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

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

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

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

Для оказания помощи в обнаружении потерь отправителем конечной точке следует создавать и отправлять кадр ACK без задержки при получении пакета с запросом подтверждения, а также:

  • при получении пакета с номером меньше чем в другом полученном пакете с запросом подтверждения;

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

Точно так же пакеты с кодом ECN CE1 в заголовке IP следует подтверждать незамедлительно для снижения времени отклика партнёра на перегрузку.

Предполагается, что алгоритмы [QUIC-RECOVERY] будут устойчивы к получателям, которые не следуют приведённым выше рекомендациям. Однако реализациям следует отходить от этих требований лишь при внимательном рассмотрении влияния на производительность для соединений данной конечной точки и других пользователей сети.

13.2.2. Частота подтверждений

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

Конечные точки полагаются на своевременные подтверждения при обнаружении потерь (см. раздел 6 в [QUIC-RECOVERY]). Контроллеры перегрузки на основе окна, такие как описано в разделе 7 [QUIC-RECOVERY], используют подтверждения для управления окном перегрузки. В обоих случаях задержка подтверждений может существенно влиять на производительность. С другой стороны, снижение частоты передачи пакетов, содержащих лишь подтверждения, уменьшает издержки на передачу и обработку в обеих конечных точках. Это может значительно повысить пропускную способность на ассиметричных каналах и снизить объем трафика подтверждений на пути возврата (см. раздел 3 в [RFC3449]).

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

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

13.2.3. Поддержка диапазонов ACK

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

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

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

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

Получатель должен сохранять ACK Range, пока не может гарантировать, что позднее не воспримет пакеты из этого диапазона. Поддержка минимального номера пакета, возрастающего по мере отбрасывания диапазонов является одним из способов решения задачи с минимальным состоянием. Получатель может отбросить все ACK Range, но он должен хранить максимальный номер успешно обработанного пакета, поскольку он служит для восстановления номеров из последующих пакетов (см. параграф 17.1). Получателю следует включать ACK Range с наибольшим полученным номером пакета в каждый кадр ACK. Поле Largest Acknowledged применяется при проверке ECN у отправителя и включение значения меньше указанного в предыдущем кадре ACK может приводить к ненужному отключению ECN (см. параграф 13.4.2).

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

13.2.4. Ограничение диапазонов путём отслеживания кадров ACK

При отправке пакета с кадром ACK поле Largest Acknowledged из этого кадра может быть сохранено. При подтверждении пакета с кадром ACK получатель может остановить подтверждение пакетов, в которых номера не больше Largest Acknowledged в переданном кадре ACK.

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

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

13.2.5. Измерение и передача задержки на хосте

Конечная точка измеряет задержки, намеренно внесённые между приёмом пакета с наибольшим порядковым номером и отправкой подтверждения. Конечная точка представляет эту задержку подтверждения в поле ACK Delay кадра ACK (см. параграф 19.3), что позволяет получателю кадра ACK уточнить преднамеренные задержки, важные для более точной оценки RTT на пути при задержке подтверждений.

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

Когда измеренная задержка подтверждения превышает max_ack_delay, конечной точке следует сообщить об измеренной задержке. Эта информация особенно полезна при согласовании, когда задержки могут быть велики (см. параграф 13.2.1).

13.2.6. Кадры ACK и защита пакета

Кадры ACK должны передаваться лишь в пакетах из одного пространства номеров с подтверждаемым пакетом (см. параграф 12.1). Например, пакеты, защищённые ключами 1-RTT, должны подтверждаться в пакетах, также защищённых ключами 1-RTT.

Пакеты, которые клиент передаёт с защитой 0-RTT, должны подтверждаться сервером в пакетах, защищённых ключами 1-RTT. Это означает, что клиент не может использовать эти подтверждения, если пакеты криптографического согласования от сервера задержаны или потеряны. Отметим, что такое же ограничение применимо и к другим данным, которые сервер защищает с помощью ключей 1-RTT.

13.2.7. Кадры PADDING, занимающие окно перегрузки

Пакеты с кадрами PADDING считаются находящимися в пути для контроля перегрузок [QUIC-RECOVERY]. Поэтому пакеты, содержащие лишь кадры PADDING, занимают окно перегрузки, не не создают подтверждений, открывающих окно перегрузки. Для предотвращения блокировки отправителю следует обеспечивать периодическую передачу других кадров в дополнение к кадрам PADDING, чтобы запросить подтверждения у получателя.

13.3. Повторная передача информации

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

  • Данные из кадров CRYPTO передаются повторно в соответствии с правилами [QUIC-RECOVERY], пока все данные не будут подтверждены. Данные в кадрах CRYPTO пакетов Initial и Handshake отбрасываются при отбрасывании ключей для соответствующего пространства номеров.

  • Прикладные данные из кадров STREAM передаются снова в других кадрах STREAM, пока конечная точка не передала RESET_STREAM для этого потока. После передачи передачи конечной точкой кадра RESET_STREAM, кадры STREAM передавать не требуется.

  • Кадры ACK содержат набор наиболее свежих подтверждений и задержку подтверждения из самого большого подтверждённого пакета, как описано в параграфе 13.2.1. Задержка передачи пакетов с кадрами ACK или повторная передача ACK может вынудить партнёра генерировать завышенную выборку RTT или неоправданный запрет ECN.

  • Отмена передачи потока в кадре RESET_STREAM передаётся, пока не будет подтверждена или пока партнёр не подтвердит все данные потока (т. е. будет достигнуто состояние Reset Recvd или Data Recvd на передающей стороне потока). Содержимое RESET_STREAM недопустимо менять при повторе передачи.

  • Аналогично, запрос на отмену передачи потока в кадре STOP_SENDING, отправляется пока принимающая сторона потока не перейдёт в состояние Data Recvd или Reset Recvd (см. параграф 3.5).

  • Сигналы закрытия соединения, включая пакеты с кадрами CONNECTION_CLOSE, не повторяются при обнаружении потери пакета. Повторная отправка этих сигналов описана в разделе 10.

  • Максимальный объем данных текущего соединения передаётся в кадрах MAX_DATA. Обновлённое значение передаётся в кадре MAX_DATA, если пакет с наиболее свежим переданным кадром MAX_DATA был объявлен потерянным или конечная точка решила обновить предел. Нужна осторожность, чтобы избежать слишком частой отправки этого кадра, поскольку предел может увеличиваться часто и это вызовет передачу слишком большого числа кадров MAX_DATA (см. параграф 4.2).

  • Текущее максимальное смещение данных потока передаётся в кадрах MAX_STREAM_DATA. Подобно MAX_DATA, обновлённое значение передаётся, если наиболее свежий кадр MAX_STREAM_DATA для потока потерян или предел обновлён, с мерами предосторожности для предотвращения отправки кадров слишком часто. Конечной точке следует останавливать передачу кадров MAX_STREAM_DATA, когда принимающая сторона потока переходит в состояние Size Known или Reset Recvd.

  • Ограничение числа потоков данного типа передаётся в кадрах MAX_STREAMS. Подобно MAX_DATA, обновлённое значение передаётся, когда пакет с наиболее свежим MAX_STREAMS для этого типа потока объявлен потерянным или при обновлении предела, с мерами предосторожности для предотвращения слишком частой отправки.

  • Сигналы блокировки передаются в кадрах DATA_BLOCKED, STREAM_DATA_BLOCKED и STREAMS_BLOCKED. Областью действия DATA_BLOCKED является соединение, STREAM_DATA_BLOCKED – поток, STREAMS_BLOCKED – конкретный тип потока. Новый кадр передаётся, если пакет с наиболее свежим кадром для области действия считается потерянным при условии блокировки конечной точки по соответствующему пределу. Эти кадры всегда включают предел, вызвавший блокировку на момент передачи.

  • Проверка живучести или пути использует кадры PATH_CHALLENGE, передаваемые периодически, пока не будет получен соответствующий кадр PATH_RESPONSE или не отпадёт необходимость в проверке. Кадры PATH_CHALLENGE включают при каждой отправке разные данные.

  • Отклики при проверке пути с использованием кадров PATH_RESPONSE передаются однократно. Предполагается, что партнёр передаст при необходимости дополнительные кадры PATH_CHALLENGE для отправки новых кадров PATH_RESPONSE.

  • Новые идентификаторы соединения передаются в кадрах NEW_CONNECTION_ID и повторяются при потере пакета с сохранением порядкового номера. Отозванные идентификаторы соединения передаются в кадрах RETIRE_CONNECTION_ID и повторяются при потере пакета.

  • Кадры NEW_TOKEN передаются повторно при потере пакета с кадром. Для этих кадров не выполняется обнаружения разупорядочения или дублирования сверх прямого сравнения содержимого кадров.

  • Кадры PING и PADDING не содержат информации, поэтому их потеря не требует восстановления.

  • Кадр HANDSHAKE_DONE должен передаваться повторно, пока не будет получено подтверждение.

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

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

Отправителю следует избегать повторной передачи информации из пакетов после их подтверждения. Это включает пакеты, подтверждённые после того, как были сочтены потерянными, что может происходить при нарушении порядка пакетов в сети. Это требует от отправителя сохранять сведения о пакетах, которые объявлены потерянными. Отправитель может отбросить эти сведения по истечении времени, достаточного для переупорядочения, например, PTO (параграф 6.2 в [QUIC-RECOVERY]), или по другим событиям, таким как ограничение памяти.

При обнаружении потерь отправитель должен принять меры по контролю перегрузки. Детали обнаружения потерь и контроля перегрузки описаны в [QUIC-RECOVERY].

13.4. Явное уведомление о перегрузке

Конечные точки QUIC могут использовать ECN [RFC3168] для обнаружения перегрузки в сети и реагирования на неё. ECN позволяет конечной точке установить код ECT2 в поле ECN пакета IP. Узел сети может тогда указать перегрузку, устанавливая код ECN-CE в поле ECN вместо отбрасывания пакета [RFC8087]. Конечные точки реагируют на сведения о перегрузке путём снижения скорости передачи, как описано в [QUIC-RECOVERY].

Для включения ECN передающая конечная точка QUIC сначала проверяет поддержку маркировки ECN на пути и возможность партнёра сообщать значения ECN в принятых пакетах IP (см. параграф 13.4.2).

13.4.1. Информирование о значениях ECN

Использование ECN требует от приёмной конечной точки считывать значение поля ECN из пакета IP, что возможно не на всех платформах. Если конечная точка не поддерживает ECN или не имеет доступа к полученным полям ECN, она не будет сообщать значения ECN из полученных пакетов.

Даже если конечная точка не устанавливает поле ECT в передаваемых пакетах, она должна предоставлять отклики о полученных маркерах ECN, если они доступны. Отказ от передачи этих значений вынудит отправителя отключить использование ECN в соединении.

При получении пакета IP с кодом ECT(0), ECT(1) или ECN-CE конечная точка с поддержкой ECN обращается к полю ECN и увеличивает соответствующее значение ECT(0), ECT(1) или ECN-CE. Значения ECN включаются в последующие кадры ACK (см. параграфы 13.2 и 19.3).

В каждом пространстве номеров пакетов поддерживаются отдельные состояния подтверждений и значения ECN. Объединённые пакеты QUIC (см. параграф 12.2) используют общий заголовок IP, поэтому счётчики ECN инкрементируются 1 раз для каждого объединённого пакета QUIC. Например, если пакеты Initial, Handshake и 1-RTT объединяются в одну дейтаграмму UDP, счётчики ECN для всех трёх пространств номеров будут инкрементироваться на 1.

Счётчики ECN инкрементируются лишь в том случае, когда пакеты QUIC из полученного пакета IP обработаны. Таким образом, дубликаты пакетов QUIC не увеличивают счётчики ECN (см. параграф 21.10 в части безопасности).

13.4.2. Проверка ECN

Неисправные устройства в сети могут повреждать или ошибочно отбрасывать пакеты с ненулевым кодом ECN. Для обеспечения связности при наличии таких устройств конечная точка проверяет значения ECN для каждого пути через сеть и отключает ECN на путях с ошибками. Для проверки ECN на новом пути:

  • конечная точка устанавливает код ECT(0) в заголовке IP ранних исходящих пакетов на новом пути к партнёру [RFC8311];

  • конечная точка отслеживает, все ли пакеты, переданные с кодом ECT, в конечном итоге будут потеряны (параграф 6 в [QUIC-RECOVERY]), что говорит об отказе при проверке ECN.

Если у конечной точки есть основания ожидать отбрасывания пакетов IP с кодом ECT неисправными элементами сети, она может устанавливать код ECT лишь для первого десятка исходящих пакетов на этом пути или в течении трёх PTO (см. параграф 6.2 в [QUIC-RECOVERY]). Если все пакеты с ненулевым кодом ECN будут потеряны, она может отключить маркировку в предположении, что та вызывает потерю пакетов. Таким образом, конечная точка пытается использовать ECN и проверяет это для каждого нового соединения при переключении на предпочтительный адрес сервера или активном переходе соединения на новый путь. Возможный алгоритм представлен в Приложении A.4. Возможны и другие методы проверки ECN на пути, а также иная стратегия маркировки. Реализации могут применять другие методы, определённые в RFC, см. [RFC8311].Реализациям, использующим код ECT(1) нужно выполнять проверку ECN с использованием сообщаемых значений ECT(1).

13.4.2.1. Прием кадров ACK со значениями ECN

Ошибочная маркировка ECN-CE в сети может снижать производительность соединения. Конечная точка, получившая кадр ACK со значением ECN, проверяет полученное значение до его использования. Эта проверка выполняется путём сравнения недавно полученного значения со значениями из последнего успешно обработанного кадра ACK. Любое увеличение счётчика ECN проверяется на основе маркировки ECN, которая применялась для пакетов, которые недавно подтверждены в кадре ACK.

Если кадр ACK снова подтверждает пакет, переданный конечной точкой с кодом ECT(0) или ECT(1), это говорит о неудачной проверке ECN при отсутствии соответствующих счётчиков ECN в кадре ACK. Такая проверка обнаруживает элементы сети, которые обнуляют поле ECN, или партнёра, не сообщающего маркировку ECN. Проверка ECN также будет неудачной, если сумма роста счётчиков ECT(0) и ECN-CE меньше числа недавно подтверждённых пакетов, которые были переданы с маркировкой ECT(0). Точно так же проверка ECN будет неудачной, если сумма увеличения счётчиков ECT(1) и ECN-CE будет меньше числа недавно подтверждённых пакетов, которые были переданы с маркировкой ECT(1). Это позволяет обнаружить перемаркировку ECN-CE в сети.

Конечная точка может пропустить подтверждения для пакета при потере кадров ACK, поэтому общее увеличение счётчиков ECT(0), ECT(1) и ECN-CE может быть больше числа пакетов, недавно подтверждённых в кадре ACK. По этой причине счётчикам ECN разрешено превышать общее число подтверждённых пакетов.

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

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

13.4.2.2. Результаты проверки ECN

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

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

14. Размер дейтаграмм

Дейтаграмма UDP может содержать один или несколько пакетов QUIC. Размер дейтаграммы определяется общим размером данных UDP в одной дейтаграмме, переносящей пакеты QUIC. В размере дейтаграммы учитываются заголовки одного или нескольких пакетов QUIC и защищённые данные, но не учитываются заголовки UDP и IP.

Максимальный размер дейтаграммы определяется как наибольший размер данных UDP (payload), которые могут быть переданы через сетевой путь в одной дейтаграмме UDP. Недопустимо использование QUIC, если путь через сеть не поддерживает дейтаграммы размером по меньшей мере 1200 байтов.

В QUIC предполагается минимальный размер пакета IP не менее 1280 байтов. Эти минимальный размер для IPv6 [IPv6] и он поддерживается в большинстве современных сетей IPv4. В предположении заголовка IP размером 40 байтов для IPv6 и 20 для IPv4, а также размера заголовка UDP 8 байтов максимальный размер дейтаграммы будет 1232 байта для IPv6 и 1252 для IPv4. Таким образом, пути через современные сети IPv4 и все сети IPv6 предполагаются пригодными для QUIC.

Примечание. Требование поддержки данных UDP размером 1200 байтов ограничивает пространство для заголовков расширения IPv6 значением 32 байта и опций IPv4 – значением 52 байта, если путь поддерживает лишь минимальное для IPv6 значение MTU в 1280 байтов. Это влияет на пакеты Initial и проверку пути.

Превышение значения 1200 байтов для максимального размера в можно обнаружить с помощью механизма PMTUD3 (см. параграф 14.2.1) или DPLPMTUD4 (см. параграф 14.3).

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

Дейтаграммы UDP недопустимо фрагментировать на уровне IP. В IPv4 [IPv4] должен устанавливаться флаг запрета фрагментирования (Don’t Fragment или DF), если это возможно.

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

14.1. Размер дейтаграмм Initial

Клиент должен расширять данные в дейтаграммах UDP с пакетом Initial по меньшей мере до наименьшего максимального размера дейтаграмм в 1200 байтов, добавляя кадры PADDING к пакету Initial или объединяя пакет Initial с другими (см. параграф 12.2). Пакет Initial можно объединить даже с недействительным пакетом, который получатель отбросит. Сервер также должен расширять данные всех дейтаграмм UDP с пакетом Initial, запрашивающим подтверждение, до наименьшего максимального размера дейтаграмм в 1200 байтов.

Передача дейтаграмм UDP такого размера гарантирует поддержку на пути через сеть приемлемого значения PMTU в обоих направлениях. Кроме того, расширение клиентом пакетов Initial помогает снизить амплитуду атак с усилением, вызываемых ответами сервера по непроверенным адресам клиентов (см. раздел 8).

Дейтаграммы с пакетом Initial могут иметь размер больше 1200 байтов, если отправитель считает, что путь в сети и партнёр поддерживают такой размер.

Сервер должен отбрасывать пакет Initial, переданный в дейтаграмме UDP с объёмом данных меньше наименьшего максимума в 1200 байтов. Сервер может также незамедлительно закрыть соединение, передав кадр CONNECTION_CLOSE с кодом ошибки PROTOCOL_VIOLATION (см. параграф 10.2.3).

Сервер также должен ограничивать число байтов, передаваемых до проверки адреса клиента (см. раздел 8).

14.2. MTU на пути

PMTU определяет максимальный размер пакета IP с учётом заголовков IP и UDP, а также данных UDP, включая один или несколько заголовков пакетов QUIC и защищённые данные. PMTU может зависеть от характеристик пути и меняться с течением времени. Максимальный размер данных UDP (payload), которые конечная точка может передать в данный момент называется максимальным размером дейтаграммы для конечной точки.

Конечной точке следует применять механизм DPLPMTUD (параграф 14.3) или PMTUD (параграф 14.2.1) для определения максимального размера (без фрагментации) дейтаграмм на пути к получателю. При отсутствии этих механизмов конечным точкам QUIC не следует передавать дейтаграммы размером больше наименьшего максимума.

DPLPMTUD и PMTUD передают дейтаграммы размером больше текущего максимума, называемые зондами PMTU. Всем пакетам QUIC, передаваемым не в зондах PMTU, следует ограничивать размер для размещения в дейтаграммах максимального размера, чтобы избежать фрагментации или отбрасывания [RFC8085].

Если конечная точка QUIC определяет, что PMTU между локальным и удаленным адресом IP не позволяет передать дейтаграммы с наименьшим максимальным размером в 1200 байтов, она должна незамедлительно прекратить передачу пакетов QUIC, за исключением пакетов в зондах PMTU, а также пакетов с кадрами CONNECTION_CLOSE по соответствующему пути. Конечная точка может прервать соединение при отсутствии других путей.

Каждая пара из локального и удалённого адреса может иметь своё значение PMTU. Реализациям QUIC, использующим какой-либо механизм определения PMTU, следует поддерживать максимальный размер дейтаграмм для каждой пары адресов IP (локальный и удалённый).

Реализация QUIC может быть более консервативной при расчёте максимального размера дейтаграмм, чтобы учесть неизвестные издержки туннелирования и/или опций (расширений) в заголовках IP.

14.2.1. Обработка сообщений ICMP в PMTUD

PMTUD [RFC1191] [RFC8201] полагается на приём сообщений ICMP (т. е. IPv6 Packet Too Big), указывающий, что пакет IP отброшен из-за превышения MTU на маршрутизаторе. DPLPMTUD также может использовать такие сообщения. Этот подход имеет уязвимость для атак со стороны объектов, не способных наблюдать за пакетами, но могущим угадать используемые на пути адреса. Такие атаки позволяют снизить значение PMTU для уменьшения пропускной способности. Конечная точка должна игнорировать сообщения ICMP, заявляющие о снижении PMTU ниже наименьшего для QUIC максимума размера дейтаграмм.

В требованиях к генерации ICMP [RFC1812] [RFC4443] сказано, что в пакет следует включать максимально возможную часть исходного пакета без превышения минимального MTU для версии IP. Размер включаемой в сообщение части пакета может быть меньше или информация может быть непонятной, как указано в параграфе 1.1 [DPLPMTUD].

Конечным точкам QUIC, использующим PMTUD, следует проверять сообщения ICMP для защиты от вставки пакетов, как указано в [RFC8201] и параграфе 5.2 [RFC8085]. Для этой проверки следует использовать включённую в сообщение часть пакета для сопоставления сообщения ICMP с соответствующим транспортным соединением (см. параграф 4.6.1 в [DPLPMTUD]). Проверка сообщения ICMP должна включать сопоставление адреса IP и порта UDP [RFC8085], а по возможности идентификатор соединения для активной сессии QUIC. Конечное точке следует игнорировать сообщения ICMP, не прошедшие проверку.

Конечной точке недопустимо увеличивать PMTU на основе сообщений ICMP (см. п. 6 в разделе 3 [DPLPMTUD]). Снижение максимального размера дейтаграмм QUIC в ответ на сообщения ICMP может быть предварительным, пока алгоритм обнаружения потерь QUIC не укажет, что пакет был действительно потерян.

14.3. Определение PMTU для уровня пакетизации дейтаграмм

DPLPMTUD [DPLPMTUD] полагается на отслеживание потерь или подтверждений пакетов QUIC, переданных в зондах PMTU. Зонды PMTU для DPLPMTUD, использующие кадр PADDING, реализуют «Зондирование с использованием заполнения», описанное в параграфе 4.1 [DPLPMTUD].

Конечным точкам следует устанавливать исходное значение BASE_PLPMTU (параграф 5.1 в [DPLPMTUD]) в соответствии с наименьшим максимальным размером дейтаграмм QUIC. MIN_PLPMTU совпадает с BASE_PLPMTU.

Конечные точки QUIC, реализующие DPLPMTUD, поддерживают максимальный размер пакета DPLPMTUD (Maximum Packet Size или MPS) (параграф 4.4 в [DPLPMTUD]) для каждой пары из локального и удалённого адреса IP. Это соответствует максимальному размеру дейтаграмм.

14.3.1. DPLPMTUD и связность для Initial

С точки зрения DPLPMTUD протокол QUIC является уровнем пакетизации (Packetization Layer или PL) с подтверждениями. Поэтому отправитель QUIC может перейти в состояние DPLPMTUD BASE (параграф 5.2 в [DPLPMTUD]) по завершении согласования QUIC.

14.3.2. Проверка сетевого пути с DPLPMTUD

QUIC является PL с подтверждениями, поэтому отправитель QUIC не реализует DPLPMTUD CONFIRMATION_TIMER в состоянии SEARCH_COMPLETE (см. параграф 5.2 в [DPLPMTUD]).

14.3.3. Обработка сообщений ICMP в DPLPMTUD

Конечная точка, применяющая DPLPMTUD, требует проверки любого полученного сообщения ICMP PTB до использования сведений PTB, как указано в параграфе 4.6 [DPLPMTUD]. В дополнение к проверке порта UDP протокол QUIC проверяет сообщение ICMP путём использования других сведений PL (например, проверку идентификатора соединения во включённой в сообщение ICMP части исходного пакета).

Рассмотренные в параграфе 14.2.1 вопросы обработки сообщений ICMP применимы и к сообщениям, используемым DPLPMTUD.

14.4. Отправка зондов QUIC PMTU

Зонды PMTU являются пакетами с запросом подтверждения.

Конечные точки могут ограничивать содержимое зондов PMTU кадрами PING и PADDING, поскольку пакеты с размером, превышающий текущий максимум для дейтаграмм, с большой вероятностью будут отброшены сетью. Поэтому потеря пакета QUIC в зонде PMTU не является надёжной индикацией перегрузки и ей не следует вызывать реакцию механизма контроля перегрузок (см. п. 7 в разделе 3 [DPLPMTUD]). Однако зонды PMTU занимают окно перегрузки, что может задерживать последующую передачу данных приложения.

14.4.1. Зонды PMTU с Source Connection ID

Конечные точки, полагающиеся на поле Destination Connection ID при маршрутизации входящих пакетов QUIC, вероятно потребуют включения идентификатора соединения в зонды PMTU для корректной маршрутизации возвращаемых сообщений ICMP (параграф 14.2.1). Однако поле Source Connection ID содержат лишь длинные заголовки (параграф 17.2), а пакеты с таким заголовком не шифруются и не подтверждаются партнёром после завершения согласования.

Одним из способов создания зонда PMTU является объединение (см. параграф 12.2) пакета с длинным заголовком, такого как Handshake или 0-RTT (параграф 17.2) и пакета с коротким заголовком в одну дейтаграмму UDP. Если полученный зонд PMTU достигает конечной точки, пакет с длинным заголовком она проигнорирует, но подтвердит пакет с коротким заголовком. Если зонд PMTU вызывает отправку сообщения ICMP, в это сообщение будет включена первая часть пробного пакета. Если поле Source Connection ID попадает в эту часть, оно может служить для маршрутизации или проверки сообщения ICMP.

Примечание. Цель использования пакета с длинным заголовком заключается лишь в попытке включить поле Source Connection ID в часть пакета, возвращаемую в сообщении ICMP. Этот пакет не обязан быть действительным и его можно передавать даже в том случае, когда пакеты данного типа не используются.

15. Версии

Версия QUIC указывается 32-битовым целым числом без знака. Значение 0x00000000 зарезервировано для согласования версий, а текущая версия протокола имеет номер 0x00000001.

Другие версии QUIC могут отличаться свойствами. Набор свойств QUIC, гарантированных в любой версии, описан в [QUIC-INVARIANTS].

Версия 0x00000001 протокола QUIC применяет TLS в качестве протокола криптографического согласования, как указано в [QUIC-TLS].

Версии, где 16 старших битов имеют значение 0, зарезервированы для использования в согласованных IETF документах.

Версии, соответствующие шаблону 0x?a?a?a?a, зарезервированы для использования в принудительном согласовании версии, когда принимается любой номер версии, где 4 младших бита каждого байта имеют двоичное значение 1010. Клиент или сервер может анонсировать поддержку любой из этих зарезервированных версий.

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

16. Представление целочисленных полей переменного размера

В пакетах и кадрах QUIC широко применяется представление неотрицательных целых чисел с переменным размером. Такое представление обеспечивает меньший размер для небольших целых чисел.

QUIC резервирует 2 старших бита для представления размера числа двоичным логарифмом. Остальные биты служат для значения числа с использованием сетевого порядка байтов. Это означает представление целых чисел 1, 2, 4 или 8 байтами и значения этих чисел выражаются 6, 14, 30 или 62 байтами, соответственно (таблица 4).

Таблица 4. Сводка представления целых чисел.

2 старших бита

Число байтов

Число битов значения

Диапазон

00

1

6

0-63

01

2

14

0-16383

10

4

30

0-1073741823

11

8

62

0-4611686018427387903

Пример алгоритма декодирования и образцы кодирования приведены в Приложении A.1.

Значения не требуется кодировать с минимально возможным размером за исключением поля Frame Type (параграф 12.4).

Версии (раздел 15), номера пакетов в заголовках (раздел 17.1) и размер идентификатора соединения в длинном заголовке (параграф 17.2) задаются целыми числами, но не используют описанного здесь кодирования.

17. Формат пакетов

Все численные значения используют сетевой порядок байтов (big endian), размеры полей указываются в битах, значения полей указаны в шестнадцатеричном формате.

17.1. Кодирование и декодирование номера пакетов

Номера пакетов указываются числами от 0 до 262-1 (параграф 12.3). При указании в заголовке они имеют размер от 1 до 4 байтов. Число используемых битов уменьшается за счёт включения лишь младших битов порядкового номера. Номер пакета защищается, как указано в параграфе 5.4 [QUIC-TLS].

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

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

На стороне получателя защита порядкового номера снимается до восстановления полного номера. Затем восстанавливается полный номер на основе числа присутствующих значимых битов, их значений и наибольшего номера, полученного в успешно аутентифицированном пакете. Восстановление полного номера требуется для полного снятия защиты пакета. После снятия защиты заголовка номер пакета декодируется путём нахождения номера, ближайшего к следующему ожидаемому пакету, которым служит пакет с номером на 1 больше максимального номера принятого пакета. Псевдокод и примеры декодирования порядкового номера представлены в Приложении A.3.

17.2. Пакеты с длинным заголовком

     Long Header Packet {
     Header Form (1) = 1,
     Fixed Bit (1) = 1,
     Long Packet Type (2),
     Type-Specific Bits (4),
     Version (32),
     Destination Connection ID Length (8),
     Destination Connection ID (0..160),
     Source Connection ID Length (8),
     Source Connection ID (0..160),
     Type-Specific Payload (..),
   }

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


Длинные заголовки применяются в пакетах, передаваемых до организации ключей 1-RTT. Когда ключи 1-RTT доступны, отправитель переходит к передаче пакетов с коротким заголовком (параграф 17.3). Длинная форма позволяет представить особые пакеты, такие как Version Negotiation, в едином формате с фиксированным размером. Поля пакетов с длинным заголовком перечислены ниже.

Header Form

Старший бит (0x80) байта 0 (первый байт) устанавливается в длинном заголовке.

Fixed Bit

Следующий бит (0x40) байта 0 устанавливается (1), если пакет не относится к Version Negotiation. Пакеты со сброшенным битом считаются в этой версии недействительными и должны отбрасываться. Установка этого бита позволяет QUIC сосуществовать с другими протоколами, см. [RFC7983].

Long Packet Type

Два следующих бита (маска 0x30) байта 0 указывают тип пакета (см. таблицу 5).

Type-Specific Bits

Семантика 4 младших битов (маска 0x0f) байта 0 определяется типом пакета.

Version

QUIC Version – 32-битовое поле, следующее за первым байтом, указывающее используемую версию QUIC и определяющее интерпретацию остальных полей протокола.

Destination Connection ID Length

Байт после номера версии указывает размер (в байтах) следующего за ним поля Destination Connection ID, представляемый 8-битовым целым числом без знака. В QUIC версии 1 этому значению недопустимо превосходить 20. Конечная точка версии 1, получившая заголовок со значением больше 20 в этом поле, должна отбросить пакет. Для корректного формирования пакета Version Negotiation серверам следует поддерживать возможность чтения более длинного идентификатора соединения из других версий QUIC.

Destination Connection ID

Поле Destination Connection ID следует за полем Destination Connection ID Length, указывающим его размер. Использование этого поля описано в параграфе 7.2.

Source Connection ID Length

Байт после поля Destination Connection ID указывает размер (в байтах) следующего за ним поля Source Connection ID, представленный 8-битовым целым числом без знака. В QUIC версии 1 этому значению недопустимо превосходить 20. Конечная точка версии 1, получившая заголовок со значением больше 20 в этом поле, должна отбросить пакет. Для корректного формирования пакета Version Negotiation серверам следует поддерживать возможность чтения более длинного идентификатора соединения из других версий QUIC.

Source Connection ID

Поле Source Connection ID следует за полем Source Connection ID Length, указывающим его размер. Использование этого поля описано в параграфе 7.2.

Type-Specific Payload

Оставшаяся часть пакета (при её наличии) зависит от типа пакета.

В этой версии QUIC определены показанные в таблице 5 типы пакетов с длинным заголовком.

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

Тип

Имя

Параграф

0x00

Initial

17.2.2. Начальный пакет

0x01

0-RTT

17.2.3. Пакет 0-RTT

0x02

Handshake

17.2.4. Пакет согласования

0x03

Retry

17.2.5. Пакет Retry

Бит формы заголовка, поля размера идентификаторов соединения и самих идентификаторов, а также поле Version в длинном заголовке не зависят от версии. Остальные поля первого байта зависят от версии протокола. В [QUIC-INVARIANTS] описана интерпретация пакетов разных версий QUIC. Интерпретация этих полей и данных (payload) определяется версией и типом пакета. Задаваемая типом семантика для данной версии описана в следующих параграфах, однако некоторые типы пакетов с длинным заголовком в этой версии QUIC содержат дополнительные поля.

Reserved Bits

Два бита (маска 0x0c) байта 0 зарезервированы для нескольких типов пакетов. Эти биты охватывается защитой заголовка (см. параграф 5.4 в [QUIC-TLS]). До установки защиты биты должны иметь значение 0. Конечная точка должна считать получение пакета с отличными от 0 значениями этих битов после снятия защиты пакета и заголовка ошибкой соединения типа PROTOCOL_VIOLATION. Отбрасывание такого пакета после снятия лишь защиты заголовка может раскрывать конечную точку для атаки (см. параграф 9.5 в [QUIC-TLS]).

Packet Number Length

В типах пакетов с полем Packet Number два младших бита (маска 0x03) байта 0 указывают размер поля Packet Number, представленный 2-битовым целым число без знака на 1 меньше фактического размера поля Packet Number в байтах. Т. е. размер поля Packet Number определяется добавлением 1 к значению этого поля. Эти биты охватывается защитой заголовка (см. параграф 5.4 в [QUIC-TLS]).

Length

Размер оставшейся части пакета (поля Packet Number и Payload) в байтах, представленный целым числом без знака с переменным размером (раздел 16).

Packet Number

Поле размером от 1 до 4 Байтов, охватываемое защитой заголовка (см. параграф 5.4 в [QUIC-TLS]). Размер поля Packet Number представлен в поле Packet Number Length байта 0, как описано выше.

Packet Payload

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

17.2.1. Пакет согласования версии

Пакет Version Negotiation по своей природе не зависит от версии. При получении клиентом пакет будет идентифицирован как Version Negotiation по полю Version = 0. Пакет согласования версии служит откликом на пакет клиент, запросивший у сервера не поддерживаемую тем версию. Пакет передаётся только серверами.

   Version Negotiation Packet {
     Header Form (1) = 1,
     Unused (7),
     Version (32) = 0,
     Destination Connection ID Length (8),
     Destination Connection ID (0..2040),
     Source Connection ID Length (8),
     Source Connection ID (0..2040),
     Supported Version (32) ...,
   }

Рисунок 14. Пакет согласования версии.


В поле Unused сервер устанавливает произвольное значение, а клиент должен игнорировать это поле. Если QUIC может мультиплексироваться с другими протоколами (см. [RFC7983]), серверу следует установить старший бит поля (0x40), чтобы в пакетах Version Negotiation было установлено поле Fixed Bit. Отметим, что в других версиях QUIC эта рекомендация может отсутствовать.

Поле Version в пакете Version Negotiation должно иметь значение 0x00000000.

Сервер должен включить значение Source Connection ID из полученного от клиента пакета в поле Destination Connection ID. Значение поля Source Connection ID должно копироваться из поля Destination Connection ID в полученном пакете, которое клиент выбрал случайно. Возврат обоих идентификаторов соединения даёт клиенту уверенность в том, что сервер получил запрос от клиента и пакет Version Negotiation не был создан объектом, который не видел пакета Initial.

В будущих версиях QUIC могут смениться требования к размеру идентификаторов соединения. В частности, для них может выбран меньший минимальный размер или больший максимальный. Зависящие от версии правилам для идентификаторов соединения недопустимо учитывать при принятии решения об отправке пакета Version Negotiation.

Оставшаяся часть пакета Version Negotiation содержит список 32-битовых номеров версий, поддерживаемых сервером.

Пакеты Version Negotiation не подтверждаются и передаются лишь в ответ на пакет, указывающий неподдерживаемую версию (см. параграф 5.)2.2.

Пакет Version Negotiation не включает полей Packet Number и Length, имеющихся в других пакетах с длинным заголовком, поэтому такой пакет занимает дейтаграмму UDP целиком. Серверу недопустимо передавать более 1 пакета Version Negotiation в ответ на одну дейтаграмму UDP. Процесс согласования версии описан в разделе 6.

17.2.2. Начальный пакет

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

   Initial Packet {
     Header Form (1) = 1,
     Fixed Bit (1) = 1,
     Long Packet Type (2) = 0,
     Reserved Bits (2),
     Packet Number Length (2),
     Version (32),
     Destination Connection ID Length (8),
     Destination Connection ID (0..160),
     Source Connection ID Length (8),
     Source Connection ID (0..160),
     Token Length (i),
     Token (..),
     Length (i),
     Packet Number (8..32),
     Packet Payload (8..),
   }

Рисунок 15. Пакет Initial.


Пакет Initial содержит длинный заголовок с полями Length и Packet Number (см. параграф 17.2). Первый байт содержит биты Reserved и Packet Number Length (см. параграф 17.2). Между полями Source Connection ID и Length размещаются два дополнительных поля, специфических для пакетов Initial.

Token Length

Целое число переменного размера, задающее размер поля Token в байтах. Значение 0 указывает отсутствие маркера. Пакеты Initial от сервера должны содержать Token Length = 0 и клиент, получающий пакет Initial с ненулевым значением Token Length должен отбросить пакет или установить ошибку соединения типа PROTOCOL_VIOLATION.

Token

Значение маркера, представленное ранее в пакете Retry или кадре NEW_TOKEN (см. параграф 8.1).

Чтобы предотвратить вмешательство промежуточных устройств, не знающих о версии, пакеты Initial защищаются с ключами, зависящими от соединения и версии (ключи Initial), как описано в [QUIC-TLS]. Эта защита не обеспечивает конфиденциальности и целостности при атаках с возможностью наблюдения пакетов, но препятствует злоумышленникам, не способным наблюдать пакеты, организовать атаку с фиктивными пакетами Initial.

Клиент и сервер могут применять пакеты типа Initial для любых пакетов, включающих сообщение начального криптографического согласования. Сюда входят все случаи, когда нужно создавать новые пакеты начального криптографического согласования, такие как пакеты, передаваемые после пакета Retry (см. параграф 17.2.5).

Сервер передаёт свой первый пакет Initial в ответ на клиентский пакет Initial и может передать несколько пакетов Initial. Для обмена криптографическими ключами может потребоваться несколько круговых обходов или повтор передачи.

Данные в пакете Initial включают кадр(ы) CRYPTO с сообщением криптографического согласования, кадры ACK или оба типа. Разрешены также кадры PING, PADDING, CONNECTION_CLOSE типа 0x1c. Конечная точка, получившая пакет Initial с кадрами иных типов, может отбросить пакет как ложный или считать его ошибкой соединения.

Первый пакет от клиента всегда включает кадр CRYPTO, содержащий начало или все сообщение криптографического согласования. Первый кадр CRYPTO всегда начинается со смещения 0 (см. раздел 7).

Отметим, что при передаче сервером TLS HelloRetryRequest (параграф 4.7 в [QUIC-TLS]) клиент будет передавать другую серию пакетов Initial, которые будут продолжать криптографическое согласования и включать кадры CRYPTO, начинающиеся со смещения, соответствующего размеру кадров CRYPTO в первой отправке пакетов Initial.

17.2.2.1. Прекращение использования пакетов Initial

Клиент прекращает отправку и обработку пакетов Initial при отправке своего первого пакета Handshake, сервер – при получении своего первого пакета Handshake. Хотя пакеты ещё могут оставаться в сети или ждать подтверждения, дополнительные пакеты Initial больше не нужны с этого момента. Ключи защиты пакетов Initial отбрасываются (см. параграф 4.9.1 в [QUIC-TLS]) вместе с состояниями восстановления потерь и контроля перегрузки (см. параграф 6.4 в [QUIC-RECOVERY]). Данные из кадров CRYPTO отбрасываются (и не передаются повторно) после отбрасывания ключей Initial.

17.2.3. Пакет 0-RTT

Пакет 0-RTT использует длинный заголовок типа 0x01, за которым следуют поля Length и Packet Number (см. параграф 17.2). Первый байт содержит поля Reserved и Packet Number Length (см. параграф 17.2). Пакеты 0-RTT используются для передачи «ранних» данных от клиента к серверу как части первой отправки до завершения согласования. В процессе согласования TLS сервер может воспринять или отвергнуть эти данные. Обсуждение данных 0-RTT и связанных с ними ограничений приведено в параграфе 2.3 [TLS13].

   0-RTT Packet {
     Header Form (1) = 1,
     Fixed Bit (1) = 1,
     Long Packet Type (2) = 1,
     Reserved Bits (2),
     Packet Number Length (2),
     Version (32),
     Destination Connection ID Length (8),
     Destination Connection ID (0..160),
     Source Connection ID Length (8),
     Source Connection ID (0..160),
     Length (i),
     Packet Number (8..32),
     Packet Payload (8..),
   }

Рисунок 16. Пакет 0-RTT.


Номера пакетов с защитой 0-RTT используют то же пространство, что и защищённые пакеты 1-RTT.

Получение клиентом пакета Retry говорит, что пакеты 0-RTT вероятно были потеряны или отброшены сервером. Клиенту следует попытаться повторно передать пакеты 0-RTT после отправки нового пакета Initial. Для новых пакетов должны использоваться новые номера, как указано в параграфе 17.2.5.3, поскольку повторное использование номеров может ставить защиту пакетов под угрозу.

Клиент получает подтверждения для его пакетов 0-RTT лишь по завершении согласования, как указано в параграфе 4.1.1 [QUIC-TLS].

Клиенту недопустимо передавать пакеты 0-RTT после начала обработки пакетов 1-RTT от сервера. Это значит, что пакеты 0-RTT не могут содержать отклики на кадры из пакетов 1-RTT. Например, клиент не может передать кадр ACK в пакете 0-RTT, поскольку этот кадр может подтверждать лишь пакет 1-RTT. Подтверждение для пакета 1-RTT должно передаваться в пакете 1-RTT.

Серверу следует считать нарушение запомненных ограничений (параграф 7.4.1) ошибкой соединения подходящего типа (например, FLOW_CONTROL_ERROR при нарушении ограничения для данных потока).

17.2.4. Пакет согласования

Пакеты Handshake используют длинный заголовок типа 0x02, за которым следуют поля Length и Packet Number (см. параграф 17.2). Первый байт содержит поля Reserved и Packet Number Length (см. параграф 17.2). Пакеты служат для передачи сообщений криптографического согласования и подтверждений от сервера и клиента.

   Handshake Packet {
     Header Form (1) = 1,
     Fixed Bit (1) = 1,
     Long Packet Type (2) = 2,
     Reserved Bits (2),
     Packet Number Length (2),
     Version (32),
     Destination Connection ID Length (8),
     Destination Connection ID (0..160),
     Source Connection ID Length (8),
     Source Connection ID (0..160),
     Length (i),
     Packet Number (8..32),
     Packet Payload (8..),
   }

Рисунок 17. Защищенный пакет Handshake.


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

Поле Destination Connection ID в пакете Handshake содержит идентификатор соединения выбранный получателем пакета, Source Connection ID – идентификатор соединения, который желает использовать отправитель (параграф 7.2).

Пакеты Handshake имеют своё пространство номеров, поэтому сервер передаёт первый пакет Handshake с номером 0.

Данные (payload) этого пакета включают кадры CRYPTO и могут включать PING, PADDING или ACK. Пакеты Handshake могут содержать кадры CONNECTION_CLOSE типа 0x1c. Конечная точка должна считать получения пакета Handshake с кадрами других типов ошибкой соединения PROTOCOL_VIOLATION.

Подобно пакетам Initial (см. параграф 17.2.2.1), данные в кадрах CRYPTO пакетов Handshake отбрасываются (и не передаются повторно), когда ключи защиты Handshake отбрасываются.

17.2.5. Пакет Retry

Как показано на рисунке 18, пакет Retry использует длинный заголовок с типом 0x03 и служит для передачи маркера проверки адреса, созданного отправителем. Пакет применяется сервером, желающим выполнить повтор (см. параграф 8.1).

   Retry Packet {
     Header Form (1) = 1,
     Fixed Bit (1) = 1,
     Long Packet Type (2) = 3,
     Unused (4),
     Version (32),
     Destination Connection ID Length (8),
     Destination Connection ID (0..160),
     Source Connection ID Length (8),
     Source Connection ID (0..160),
     Retry Token (..),
     Retry Integrity Tag (128),
   }

Рисунок 18. Пакет Retry.


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

Retry Token

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

Retry Integrity Tag

Тег, определённый в параграфе 5.8 (Целостность пакета Retry) [QUIC-TLS].

17.2.5.1. Отправка пакета Retry

Сервер указывает в поле Destination Connection ID идентификатор соединения, включенный клиентом в поле Source Connection ID пакета Initial. В поле Source Connection ID сервер помещает выбранный им идентификатор соединения. В этом поле недопустимо указывать значение Destination Connection ID из переданного клиентом пакета. Клиент должен отбрасывать пакет Retry, в котором поле Source Connection ID совпадает с полем Destination Connection ID в пакете Initial от клиента. Клиент должен использовать значение Source Connection ID из пакета Retry в полях Destination Connection ID последующих пакетов, которые он передаёт.

Сервер может передавать пакеты Retry в ответ на Initial и 0-RTT. Сервер может отбрасывать или буферизовать полученные пакеты 0-RTT и может отправлять несколько пакетов Retry при получении Initial или 0-RTT. Серверу недопустимо передавать более одного пакета Retry в ответ на одну дейтаграмму UDP.

17.2.5.2. Обработка пакета Retry

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

Клиенты должны отбрасывать пакеты Retry с полем Retry Integrity Tag, которое они не могут проверить (параграф 5.8 в [QUIC-TLS]). Это препятствует внедрению пакетов Retry злоумышленниками и защищает от случайно повреждённых пакетов Retry. Клиент должен отбрасывать пакеты с пустым (размер 0) полем Retry Token.

Клиент отвечает на Retry пакетом Initial с маркером из пакета Retry для продолжения организации соединения. Клиент помещает в поле Destination Connection ID пакета Initial значение поля Source Connection ID из пакета Retry. Смена поля Destination Connection ID ведёт к изменению ключей, применяемых для защиты пакета Initial. Клиенту недопустимо менять Source Connection ID, поскольку сервер может включать идентификатор соединения в логику проверки маркера (см. параграф 8.1.4).

Пакет Retry не включает номера и не может быть явно подтверждён клиентом.

17.2.5.3. Продолжение согласования после пакета Retry

Последующие пакеты Initial от клиента включают идентификатор соединения и маркер из пакета Retry. Клиент копирует поле Source Connection ID из Retry в поле Destination Connection ID и использует это значение, пока не будет получен пакет Initial с обновлённым значением (см. параграф 7.2). Значение поля Token копируется во все последующие пакеты Initial (см. параграф 8.1.2).

Помимо обновления полей Destination Connection ID и Token, на передаваемый клиентом пакет Initial распространяются те же ограничения, которые применяются к первому пакету Initial. Клиент должен использовать сообщение криптографического согласования, включённое в этот пакет. Сервер может считать пакет с другим сообщением криптографического согласования ошибкой соединения или отбрасывать его. Отметим, что включение поля Token сокращает пространство, доступное для сообщения криптографического согласования, что может потребовать от клиента передачи нескольких пакетов Initial.

Клиент может попытаться использовать 0-RTT после приёма сообщения Retry, передавая пакеты 0-RTT с полученным от сервера идентификатором соединения.

Клиенту недопустимо сбрасывать номер пакета в каком-либо из пространство номеров после обработки пакета Retry. В частности, пакеты 0-RTT содержат конфиденциальные данные, которые, скорей всего, будут передаваться повторно после получения пакета Retry. Ключи, применяемые для этих новых пакетов 0-RTT, не будут меняться в результате отклика на пакет Retry. Однако данные в этих пакетах могут отличаться от переданных ранее. Отправка новых пакетов с теми же порядковыми номерами может ставить под угрозу защиту пакетов, поскольку для защиты другого содержимого могут использоваться те же ключ и nonce. Сервер может прервать соединение при обнаружении сброса порядкового номера клиентом.

Идентификаторы соединения в пакетах Initial и Retry, которыми обмениваются клиент и сервер, копируются в транспортные параметры и проверяются, как описано в параграфе 7.3.

17.3. Пакеты с коротким заголовком

В этой версии QUIC определён единственный пакет, использующий короткий заголовок.

17.3.1. Пакет 1-RTT

   1-RTT Packet {
     Header Form (1) = 0,
     Fixed Bit (1) = 1,
     Spin Bit (1),
     Reserved Bits (2),
     Key Phase (1),
     Packet Number Length (2),
     Destination Connection ID (0..160),
     Packet Number (8..32),
     Packet Payload (8..),
   }

Рисунок 19. Пакет 1-RTT.


Пакеты 1-RTT использует короткий и передаются заголовок после согласования версии и ключей 1-RTT.

Header Form

Старший бит (0x80) байта 0 сброшен (0) для короткого заголовка.

Fixed Bit

Следующий бит (0x40) байта 0 имеет значение 1. Пакеты, в которых этот бит сброшен, с данной версии протокола являются недействительными и должны отбрасываться. Установка этого бита (1) позволяет использовать QUIC вместе с другими протоколами [RFC7983].

Spin Bit

Третий бит (0x20) байта 0 является битом задержки и устанавливается в соответствии с параграфом 17.4.

Reserved Bits

Два следующих бита (маска 0x18) байта 0 являются резервными. Эти биты охватываются защитой заголовка (см. параграф 5.4 в [QUIC-TLS]). До применения защиты в поле должно быть установлено значение 0. Конечная точка должна считать отличное от 0 значение этого поля после снятия защиты ошибкой соединения типа PROTOCOL_VIOLATION. Отбрасывание таких пакетов после снятия защиты заголовка может делать конечную точку уязвимой для атак (см. параграф 9.5 в [QUIC-TLS]).

Key Phase

Следующий бит (0x04) байта 0 указывает фазу ключа, которая позволяет получателю пакета идентифицировать ключи, использованные для защиты пакета [QUIC-TLS]. Этот бит охватывается защитой заголовка (см. параграф 5.4 в [QUIC-TLS]).

Packet Number Length

Два младших бита (маска 0x03) байта 0 указывают размер поля Packet Number, представленный 2-битовым целым число без знака на 1 меньше фактического размера поля Packet Number в байтах. Т. е. размер поля Packet Number определяется добавлением 1 к значению этого поля. Эти биты охватывается защитой заголовка (см. параграф 5.4 в [QUIC-TLS]).

Destination Connection ID

Идентификатор соединения, выбранный предполагаемым получателем пакета (см. параграф 5.1).

Packet Number

Поле размером от 1 до 4 Байтов, охватываемое защитой заголовка (см. параграф 5.4 в [QUIC-TLS]). Размер поля Packet Number представлен в поле Packet Number Length байта 0 (см. параграф 17.1).

Packet Payload

Пакеты 1-RTT всегда включают данные, защищённые с использованием режима 1-RTT.

Бит формы заголовка и поле Destination Connection ID в коротком заголовке не зависят от версии. Остальные поля первого байта зависят от версии протокола. В [QUIC-INVARIANTS] описана интерпретация пакетов разных версий QUIC.

17.4. Spin Bit для задержки

Поле Spin Bit, определённое для пакетов 1-RTT (параграф 17.3.1), позволяет вести пассивных мониторинг задержки из точек наблюдения на пути через сеть в течение соединения. Сервер возвращает полученное значение бита, а клиент «поворачивает» (spin) его после одного RTT. Находящиеся на пути наблюдатели могут измерить время между двумя переключениями бита для оценки сквозного значения RTT в соединении.

Spin Bit применяется лишь в пакетах 1-RTT, поскольку можно измерить начальное значение RTT в соединении, наблюдая за согласованием (handshake). Поэтому бит становится доступным по завершении согласования версии и организации соединения. Измерение в пути и использование бита дополнительно рассматриваются в [QUIC-MANAGEABILITY].

Spin Bit является необязательным в этой версии QUIC. Конечная точка, не поддерживающая это свойство, должна отключить его, как описано ниже. Каждая из конечных точек в одностороннем порядке управляет включением этого бита для соединения. Реализации должны позволять администраторам на стороне клиента и сервера включать или отключать Spin Bit глобально или на уровне соединения. Деже в случаях, когда Spin Bit не отключён администратором, конечная точка должна отключать его использование для по меньшей мере для одного случайного выбранного из каждых 16 путей через сеть или 16 идентификаторов соединения, чтобы обеспечить присутствие в сети соединения QUIC с отключённым Spin Bit. Поскольку каждая конечная точка отключает свойство независимо, это обеспечивает отключение сигнала Spin Bit примерно на каждом восьмом пути через сеть.

При отключённом Spin Bit конечная точка может установить для бита любое значение и должна игнорировать входящее значение. Рекомендуется устанавливать для Spin Bit случайное значение независимо для каждого пакета или идентификатора соединения.

Если Spin Bit включён для соединения, конечная точка поддерживает значение для каждого пути через сеть и устанавливает бит в заголовках пакетов в соответствии с текущим сохраненным значением, когда по этому пути отправляется пакет 1-RTT. Spin Bit инициализируется значением 0 в конечной точке для каждого пути через сеть. Каждая конечная точка также запоминает наибольший номер пакета, увиденный её партнёром на каждом пути.

Когда сервер получает пакет 1-RTT с большим порядковым номером, чем видел сервер до этого на данном пути через сеть, он устанавливает для пути значение Spin Bit из полученного пакета. Когда клиент получает пакет 1-RTT, увеличивающий порядковый номер, видимый клиентом в пакетах от сервера для данного пути, он устанавливает для этого пути инвертированное значение Spin Bit из полученного пакета.

Конечная точка сбрасывает в 0 значение Spin Bit для пути при смене идентификатора соединения на этом пути.

18. Кодирование транспортных параметров

Поле extension_data расширения quic_transport_parameters, определённое в [QUIC-TLS], содержит транспортные параметры QUIC, кодируемые в виде последовательности, как показано на рисунке 20.

   Transport Parameters {
     Transport Parameter (..) ...,
   }

Рисунок 20. Последовательность транспортных параметров.


Каждый параметр представляется триплетом (идентификатор, размер, значение), как показано на рисунке 21

   Transport Parameter {
     Transport Parameter ID (i),
     Transport Parameter Length (i),
     Transport Parameter Value (..),
   }

Рисунок 21. Кодирование транспортных параметров.


Поле Transport Parameter Length указывает размер поля Transport Parameter Value в октетах.

QUIC кодирует параметры транспорта в последовательности байтов, включаемые в криптографическое согласование.

18.1. Резервные параметры транспорта

Транспортные параметры с идентификаторами вида 31*N+27 при целочисленных N зарезервированы для выполнения требования по игнорированию неизвестных параметров. Эти параметры не имеют семантики и могут включать произвольные значения.

18.2. Определения транспортных параметров

В этом параграфе детализируются транспортные параметры, определённые в документе. Многие из перечисленных параметров транспорта имеют целочисленные значения и для них используется кодирование с переменным размером, описанное в разделе 6. Для неуказанных параметров по умолчанию принимается значение 0, если не указано иное.

original_destination_connection_id (0x00)

Значение поля Destination Connection ID из первого пакета Initial от клиента (см. параграф 7.3). Параметр передают только серверы.

max_idle_timeout (0x01)

Число миллисекунд максимального тайм-аута бездействия, представленное целочисленным значением. (параграф 10.1). Тайм-аут бездействия отключается, если обе точки укажут значение 0 или опустят этот параметр.

stateless_reset_token (0x02)

Маркер, используемый для проверки сброса без учёта состояния (см. параграф 10.3) и задаваемый последовательностью из 16 байтов. Этот параметр недопустимо передавать клиенту, но сервер может его отправлять. Не передав этот параметр, сервер не сможет использовать сброс без учёта состояния (параграф 10.3) для идентификатора соединения, заданного при согласовании.

max_udp_payload_size (0x03)

Максимальный размер данных UDP (payload), выраженный целым числом, для ограничения размера дейтаграмм UDP, которые эта конечная точка хочет получать. Дейтаграммы UDP с большим размером данных могут не обрабатываться их получателем. По умолчанию для этого параметра используется максимальный размер данных в дейтаграмме UDP (65527 байтов). Значения меньше 1200 являются недействительными. Этот параметр служит дополнительным ограничением размера дейтаграмм к значению MTU на пути, но является свойством конечной точки, а не пути (см. раздел 14). Предполагается, что это значение определяется пространством, выделенным конечной точкой для входящих пакетов.

initial_max_data (0x04)

Целое число, указывающее заданный в начале максимальный объем данных, которые могут быть переданы в соединении. Это эквивалентно передаче MAX_DATA (параграф 19.9) для соединения сразу после согласования.

initial_max_stream_data_bidi_local (0x05)

Целое число, задающее начальный предел управления потоком данных, для локально инициированных двухсторонних потоков. Этот предел относится к недавно созданным двухсторонним потокам, открытым конечной точкой, которая передала транспортный параметр. В параметрах клиента этот относится к потокам с идентификатором, где два младших бита имеют значение 0x00, в параметрах сервера – 0x01.

initial_max_stream_data_bidi_remote (0x06)

Целое число, задающее начальный предел управления потоком данных, для инициированных партнёром двухсторонних потоков. Этот предел относится к недавно созданным двухсторонним потокам, открытым конечной точкой, которая получила транспортный параметр. В параметрах клиента этот относится к потокам с идентификатором, где два младших бита имеют значение 0x01, в параметрах сервера – 0x00.

initial_max_stream_data_uni (0x07)

Целое число, задающее начальный предел управления потоком данных, для односторонних потоков. Этот предел относится к недавно созданным односторонним потокам, открытым конечной точкой, которая получила транспортный параметр. В параметрах клиента этот относится к потокам с идентификатором, где два младших бита имеют значение 0x03, в параметрах сервера – 0x02.

initial_max_streams_bidi (0x08)

Целое число, задающее начальное ограничение числа двухсторонних потоков, которые разрешено инициировать принявшей параметр конечной станции. Если параметр отсутствует или имеет значение 0, партнёр не может создавать двухсторонних поток до передачи кадра MAX_STREAMS. Установка параметра эквивалентна отправке MAX_STREAMS (параграф 19.11) соответствующего типа с тем же значением.

initial_max_streams_uni (0x09)

Целое число, задающее начальное ограничение числа односторонних потоков, которые разрешено инициировать принявшей параметр конечной станции. Если параметр отсутствует или имеет значение 0, партнёр не может создавать двухсторонних поток до передачи кадра MAX_STREAMS. Установка параметра эквивалентна отправке MAX_STREAMS (параграф 19.11) соответствующего типа с тем же значением.

ack_delay_exponent (0x0a)

Целое число, указывающее показатель степени, используемый для декодирования поля ACK Delay в кадре ACK (параграф 19.3). По умолчанию используется значение 3 (коэффициент 8). Значения больше 20 недействительны.

max_ack_delay (0x0b)

Целое число, указывающее максимальную задержку (в миллисекундах) отправки подтверждения конечной точкой. В значении следует учитывать задержку, после которой получатель устанавливает сигнал тревоги. Например, если получатель установил таймер на 5 мсек а сигнал тревоги обычно задерживается на 1 мсек, следует задать max_ack_delay = 6 мсек. По умолчанию предполагается 25 мсек. Значения 214 и больше недействительны.

disable_active_migration (0x0c)

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

preferred_address (0x0d)

Предпочтительный адрес сервера служит для изменения адреса сервера в конце согласования, как описано в параграфе 9.6. Этот параметр передают только серверы. Сервер может выбрать предпочтительный адрес лишь для одного семейства, указав для другого нулевой адрес и порт (0.0.0.0:0 или [::]:0). Адрес IP указывается с сетевым порядком байтов.

Параметр preferred_address содержит адрес и порт для IPv4 и IPv6. За 4-байтовым полем IPv4 следует 2 байта поля IPv4, затем 16 байтов IPv6 Address и 2 байта IPv6 Port. После адресов и портов указывается поле Connection ID Length, задающее размер следующего за ним поля Connection ID. Последним является 16-байтовое поле Stateless Reset Token с маркером сброса без учёта состояния, связанным с идентификатором соединения. Формат транспортного параметра показан на рисунке 22.

Поля Connection ID и Stateless Reset Token относятся к дополнительному идентификатору соединения, имеющему номер 1 (см. параграф 5.1.1). Отправки этих полей с предпочтительным адресом обеспечивает наличие хотя бы одного не использованного активного идентификатора соединения при переходе клиента на предпочтительный адрес сервера. Синтаксис и семантика полей Connection ID и Stateless Reset Token в предпочтительном адресе такие же как для соответствующих полей в кадре NEW_CONNECTION_ID (параграф 19.15). Серверу, выбравшему пустой идентификатор соединения, недопустимо указывать предпочтительный адрес. Клиент должен считать нарушение этого требования ошибкой соединения типа TRANSPORT_PARAMETER_ERROR.

   Preferred Address {
     IPv4 Address (32),
     IPv4 Port (16),
     IPv6 Address (128),
     IPv6 Port (16),
     Connection ID Length (8),
     Connection ID (..),
     Stateless Reset Token (128),
   }

Рисунок 22. Формат предпочтительного адреса.


active_connection_id_limit (0x0e)

Целое число, задающее максимальное количество идентификаторов соединений от партнёра, которые конечная точка желает сохранить. Это значение включает идентификатор соединения, полученный при согласовании соединения, а также полученные в транспортном параметре preferred_address и кадрах NEW_CONNECTION_ID. Значение параметра active_connection_id_limit должно быть не меньше 2. Конечная точка, получившая значение меньше 2, должна закрыть соединение с ошибкой типа TRANSPORT_PARAMETER_ERROR. При отсутствии этого транспортного параметра предполагается значение 2. Если конечная точка указывает пустой идентификатор соединения, она не будет передавать кадров NEW_CONNECTION_ID, поэтому игнорирует полученное от партнёра значение active_connection_id_limit.

initial_source_connection_id (0x0f)

Значение, указанное конечной точкой в поле Source Connection ID первого пакета Initial в соединении (параграф 7.3).

retry_source_connection_id (0x10)

Значение, указанное сервером в поле Source Connection ID пакета Retry (параграф 7.3). Этот параметр передаёт только сервер.

При наличии транспортных параметров, устанавливающих начальные пределы для управления потоком данных на уровне потока (initial_max_stream_data_bidi_local, initial_max_stream_data_bidi_remote, initial_max_stream_data_uni), они эквивалентны отправке кадра MAX_STREAM_DATA (параграф 19.10) в каждом потоке соответствующего типа сразу после создания. При отсутствии транспортного параметра потоки данного типа запускаются с пределом управления потоком данных 0.

Клиенту недопустимо включать какие-либо транспортные параметры, предназначенные лишь для серверов (original_destination_connection_id, preferred_address, retry_source_connection_id, stateless_reset_token). Сервер должен считать получение такого транспортного параметра ошибкой соединения типа TRANSPORT_PARAMETER_ERROR.

19. Типы и форматы кадров

Как указано в параграфе 12.4, пакет содержит 1 или несколько кадров. В этом разделе описан формат и семантика основных типов кадров QUIC.

19.1. Кадр PADDING

Кадр PADDING (тип 0x00) не имеет семантического значения и служит для увеличения размера пакета. Заполнение может применяться для увеличения пакетов Initial до минимально требуемого размера или для защиты от анализа трафика защищённых пакетов.

   PADDING Frame {
     Type (i) = 0x00,
   }

Рисунок 23. Формат кадра PADDING.


Формат кадра PADDING показан на рисунке 23, из которого видно отсутствие в кадре содержимого. Т. е. кадр PADDING содержит лишь байт идентификатора типа.

19.2. Кадр PING

Конечные точки могут применять кадры PING (тип 0x01) для проверки живучести партнёра или его достижимости.

Формат кадра PING показан на рисунке 24, из которого видно отсутствие в кадре содержимого.

   PING Frame {
     Type (i) = 0x01,
   }

Рисунок 24. Формат кадра PING.


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

19.3. Кадр ACK

Получатели передают кадры ACK (тип 0x02 и 0x03) для информирования отправителя о приёме и обработке его пакетов. Кадр ACK включает один или несколько диапазонов ACK Range, указывающих подтверждаемые пакеты. Кадры ACK типа 0x03 содержат также кумулятивный счётчик пакетов QUIC со связанной маркировкой ECN, полученных через соединение к моменту отправки кадра. Реализации QUIC должны обрабатывать оба типа кадров, а при поддержке ECN для передаваемых пакетов им также следует использовать сведения из раздела ECN для поддержки статуса перегрузки.

Подтверждения QUIC являются безотзывными, т. е. после подтверждения пакет считается доставленным, даже если он не указан в будущем кадре ACK. Это отличается от отказа для селективных подтверждений TCP (Selective Acknowledgment или SACK) [RFC2018].

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

Пакеты Version Negotiation и Retry не могут подтверждаться, поскольку у них нет порядкового номера. Вместо кадров ACK для них используются неявные подтверждения в следующем пакете Initial, переданном клиентом.

   ACK Frame {
     Type (i) = 0x02..0x03,
     Largest Acknowledged (i),
     ACK Delay (i),
     ACK Range Count (i),
     First ACK Range (i),
     ACK Range (..) ...,
     [ECN Counts (..)],
   }

Рисунок 25. Формат кадра ACK.


Формат кадра ACK показан на рисунке 25.

Largest Acknowledged

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

ACK Delay

Целое число с переменным размером, указывающее задержку подтверждения в миллисекундах (параграф 13.2.5). Значение декодируется путём умножения поля на 2 в степени, заданной транспортным параметром ack_delay_exponent, переданным отправителем кадра ACK (параграф 18.2). По сравнению с простым заданием задержки целым числом такое кодирование позволяет указать больший диапазон тем же числом битов за счёт снижения точности.

ACK Range Count

Целое число с переменным размером, указывающее количество полей ACK Range в кадре.

First ACK Range

Целое число с переменным размером, указывающее количество непрерывных пакетов, предшествующих подтверждаемому значению Largest Acknowledged. Таким образом, меньший номер, подтверждаемый диапазоном, определяется вычитанием First ACK Range из Largest Acknowledged.

ACK Ranges

Дополнительные диапазоны пропущенных (Gap) и подтверждённых (ACK Range) пакетов (параграф 19.3.1).

ECN Counts

Три значения счётчиков ECN (см. параграф 19.3.2).

19.3.1. Диапазоны ACK

Каждое поле ACK Range состоит из чередующихся значений Gap и ACK Range Length в порядке уменьшения номеров пакетов. Поля ACK Range могут повторяться. Число значений Gap и ACK Range Length определяется полем ACK Range Count. Структура ACK Range показана на рисунке 26.

   ACK Range {
     Gap (i),
     ACK Range Length (i),
   }

Рисунок 26. Диапазоны ACK.


Gap

Целое число переменного размера, указывающее количество последовательных неподтвержденных пакетов перед пакетом с меньшим на 1 номером по сравнению с меньшим из предшествующего ACK Range.

ACK Range Length

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

В полях Gap и ACK Range Length используется относительное кодирование целых чисел для эффективности. Хотя каждое значение является положительным, значения вычитаются так, что в каждом ACK Range описывается диапазон с меньшими номерами. Каждое поле ACK Range подтверждает непрерывный диапазон пакетов, указывая число подтверждённых пакетов, предшествующих большему значению диапазона. Значение 0 указывает, что подтверждается лишь пакет с наибольшим номером. Большие значения ACK Range указывают больший диапазон с соответствующим меньшим значением для наименьшего номера пакета в диапазоне. Таким образом, по большему номеру пакета в диапазоне (largest) меньший (smallest) определяется как smallest = largest – ack_range.

ACK Range подтверждает все пакеты от меньшего до большего номера, включительно. Наибольшее значение для ACK Range определяется путём последовательного вычитания размера всех предшествующих полей ACK Range Length и Gap. Каждое значение Gap указывает диапазон пакетов, которые не подтверждаются. Число пропущенных пакетов на 1 больше значения поля Gap. Поле Gap задаёт наибольший номер пакета для последующего ACK Range выражением largest = previous_smallest – gap – 2. Если какой-либо из рассчитанных номеров имеет отрицательное значение, конечная точка должна генерировать ошибку типа FRAME_ENCODING_ERROR.

19.3.2. ECN Counts

Кадры ACK используют младший бит типа (0x03) для индикации обратной связи ECN и информирования о получении пакетов QUIC с кодами ECN ECT(0), ECT(1), ECN-CE в заголовке IP. Поле ECN присутствует лишь в кадрах ACK типа 0x03. Формат поля показан на рисунке 27.

   ECN Counts {
     ECT0 Count (i),
     ECT1 Count (i),
     ECN-CE Count (i),
   }

Рисунок 27. Формат ECN Counts.


ECT0 Count

Целое число переменного размера – количество пакетов с кодом ECT(0) в пространстве номеров кадра ACK.

ECT1 Count

Целое число переменного размера – количество пакетов с кодом ECT(1) в пространстве номеров кадра ACK.

ECN-CE Count

Целое число переменного размера – количество пакетов с кодом ECN-CE в пространстве номеров кадра ACK.

Счётчики ECN поддерживаются независимо в каждом пространстве порядковых номеров пакетов.

19.4. Кадр RESET_STREAM

Конечная точка применяет кадр RESET_STREAM (тип 0x04) для внезапной остановки передающей части потока. После отправки RESET_STREAM конечная точка прекращает передачу кадров STREAM в указанном потоке. Получатель RESET_STREAM может отбросить любые данные, уже принятые в этом потоке. Принявшая RESET_STREAM конечная точка для потока, который лишь передаёт (send-only), должна прервать соединение с ошибкой STREAM_STATE_ERROR. Формат кадра RESET_STREAM показан на рисунке 28.

   RESET_STREAM Frame {
     Type (i) = 0x04,
     Stream ID (i),
     Application Protocol Error Code (i),
     Final Size (i),
   }

Рисунок 28. Формат кадра RESET_STREAM.


Stream ID

Целое число переменного размера, представляющее идентификатор прерываемого потока.

Application Protocol Error Code

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

Final Size

Целое число переменного размера, указывающее конечный размер потока у отправителя RESET_STREAM в байтах (см. параграф 4.5).

19.5. Кадр STOP_SENDING

Конечная точка использует кадр STOP_SENDING (тип 0x05) для информирования о том, что входящие данные отбрасываются при получении по запросу приложения. STOP_SENDING запрашивает у партнёра прекращение передачи в поток. Кадр STOP_SENDING можно передать для потоков в состоянии Recv или Size Known 9см. параграф 3.2). Получение STOP_SENDING для локально инициированного потока, который ещё не создан, должно считаться ошибкой соединения типа STREAM_STATE_ERROR. Конечная точка, получившая STOP_SENDING для потока, который только принимает (receive-only), должна прервать соединение с ошибкой STREAM_STATE_ERROR. Формат кадра STOP_SENDING показан на рисунке 29.

   STOP_SENDING Frame {
     Type (i) = 0x05,
     Stream ID (i),
     Application Protocol Error Code (i),
   }

Рисунок 29. Формат кадра STOP_SENDING.


Stream ID

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

Application Protocol Error Code

Целое число переменного размера с заданным приложением кодом причины игнорирования потока отправителем (см. параграф 20.2).

19.6. Кадр CRYPTO

Кадр CRYPTO (тип 0x06) служит для передачи сообщений криптографического согласования и может передаваться во всех типах пакетов кроме 0-RTT. Кадр CRYPTO предлагает криптографическому протоколу упорядоченный поток байтов. Функционально кадры CRYPTO идентичны STREAM, но они не включают идентификатор потока, для них не применяется управления потоком данных и в кадрах нет маркеров смещения, размера и конца потока. Формат CRYPTO показан на рисунке 30.

   CRYPTO Frame {
     Type (i) = 0x06,
     Offset (i),
     Length (i),
     Crypto Data (..),
   }

Рисунок 30. Формат кадра CRYPTO.


Offset

Целое число переменного размера – байтовое смещение в потоке для данных в этом кадре CRYPTO.

Length

Целое число переменного размера, указывающее размер поля Crypto Data в этом кадре CRYPTO.

Crypto Data

данные криптографического сообщения.

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

Наибольшее смещение данных, доставляемых в потоке (сумма смещения и размера данных) не может превышать 262-1. Получение кадра сверх этого предела должно считаться ошибкой соединения типа FRAME_ENCODING_ERROR или CRYPTO_BUFFER_EXCEEDED.

В отличие от кадров STREAM, включающих идентификатор потока, кадры CRYPTO содержат данные для одного потока на уровень шифрования. Поток не имеет явного завершения, поэтому в кадрах CRYPTO не передаётся бит FIN.

19.7. Кадр NEW_TOKEN

Сервер передаёт кадр NEW_TOKEN (тип 0x07) для предоставления клиенту маркера, который тот передаёт в заголовке пакета Initial для будущего соединения. Формат кадра NEW_TOKEN показан на рисунке 31.

   NEW_TOKEN Frame {
     Type (i) = 0x07,
     Token Length (i),
     Token (..),
   }

Рисунок 31. Формат кадра NEW_TOKEN.


Token Length

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

Token

Необрабатываемый блок данных (blob), который клиент может указать в будущем пакете Initial. Пустой маркер не допустим и клиент должен считать получение кадра NEW_TOKEN с пустым полем Token ошибкой соединения типа FRAME_ENCODING_ERROR.

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

19.8. Кадр STREAM

Кадры STREAM неявно создают поток и переносят его данные. Поле Type в кадре STREAM принимает форму 0b00001XXX (или набор значений от 0x08 до 0x0f). Три младших бита типа определяют присутствующие в кадре поля.

  • Бит OFF (0x04) в типе кадра указывает наличие поля Offset. При установленном (1) биту поле Offset присутствует, а при сброшенном его нет и данные потока (Stream Data) начинаются со смещения 0 (т. е. кадр содержит первые байты потока или конец пустого потока).

  • Бит LEN (0x02) в типе кадра указывает наличие поля Length. Сброшенный (0) бит говорит, что поля Length нет и поле Stream Data продолжается до конца потока. Установленный (1) бит указывает наличе поля Length.

  • Бит FIN (0x01) указывает, что кадр содержит конец потока. Окончательный размер потока определяет сумма смещения и размера этого кадра.

Конечная точка должна прерывать соединение с ошибкой STREAM_STATE_ERROR при получении кадра STREAM для локально инициированного потока, который ещё не создан, или только передающего потока (send-only). Формат кадра STREAM показан на рисунке 32.

   STREAM Frame {
     Type (i) = 0x08..0x0f,
     Stream ID (i),
     [Offset (i)],
     [Length (i)],
     Stream Data (..),
   }

Рисунок 32. Формат кадра STREAM.


Stream ID

Целое число переменного размера – идентификатор потока (см. параграф 2.1).

Offset

Целое число переменного размера – смещение в потоке данных этого кадра STREAM. Поле присутствует при установленном бите OFF. При отсутствии поля Offset смещение принимается равным 0.

Length

Целое число переменного размера, указывающее размер поля Stream Data в этом кадре STREAM. Поле присутствует при установленном бите LEN. Если LEN = 0, поле Stream Data занимает оставшиеся байты пакета.

Stream Data

Байты указанного потока для доставки.

Когда поле Stream Data имеет размер 0, смещение в кадре STREAM указывает следующий байт, который будет передан. Первый байт потока имеет смещение 0. Наибольшее смещение в потоке (сумма смещения и размера данных) не может быть больше 262-1, поскольку невозможно предоставить кредит управления потоком данных для таких данных. Получение кадра с превышением этого предела должно считаться ошибкой соединения типа FRAME_ENCODING_ERROR или FLOW_CONTROL_ERROR.

19.9. Кадр MAX_DATA

Кадр MAX_DATA (тип 0x10) применяется в управлении потоком данных для указания партнёру максимального объёма данных, которые он может передать в соединении. Формат кадра MAX_DATA показан на рисунке 33.

   MAX_DATA Frame {
     Type (i) = 0x10,
     Maximum Data (i),
   }

Рисунок 33. Формат кадра MAX_DATA.


Maximum Data

Целое число переменного размера – максимальный объем данных (в байтах) для передачи через соединение.

Учитываются все данные, переданные в кадрах STREAM. Сумме окончательных размеров всех потоков, включая потоки в завершающих состояниях, недопустимо превышать значение, анонсированное получателем. Конечная точка должна прерывать соединение с ошибкой FLOW_CONTROL_ERROR при получении данных сверх заданного предела с учётом нарушения запомненных пределов в Early Data (см. параграф 7.4.1).

19.10. Кадр MAX_STREAM_DATA

Кадр MAX_STREAM_DATA (тип 0x11) применяется в управлении потоком данных для указания партнёру максимального объёма данных, которые он может передать в потоке. Кадр MAX_STREAM_DATA можно передавать для потоков в состоянии Recv (см. параграф 3.2). Получение MAX_STREAM_DATA для локально инициированного потока, который ещё не создан, должно считаться ошибкой соединения типа STREAM_STATE_ERROR. Конечная точка, получившая MAX_STREAM_DATA для только принимающего (receive-only) потока, должна прервать соединения с ошибкой STREAM_STATE_ERROR. Формат MAX_STREAM_DATA показан на рисунке 34.

   MAX_STREAM_DATA Frame {
     Type (i) = 0x11,
     Stream ID (i),
     Maximum Stream Data (i),
   }

Рисунок 34. Формат кадра MAX_STREAM_DATA.


Stream ID

Целое число переменного размера – идентификатор потока, на который воздействует кадр.

Maximum Stream Data

Целое число переменного размера – максимальный объем данных (в байтах) для передачи в указанном потоке.

Конечная точка учитывает максимальное смещение полученных данных, которые были переданы или приняты в потоке. Потери или нарушение порядка могут приводить к тому, что наибольшее смещение превысит размер данных, полученных в потоке. Приме кадров STREAM может не увеличивать наибольшее смещение полученных данных. Данным, переданным в потоке, недопустимо превышать максимальное значение, анонсированное партнёром. Конечная точка должна прервать соединение с ошибкой FLOW_CONTROL_ERROR при получении данных сверх заданного предела с учётом нарушения запомненных пределов в Early Data (см. параграф 7.4.1).

19.11. Кадр MAX_STREAMS

Кадр MAX_STREAMS (тип 0x12 или 0x13) указывает партнёру общее число потоков, которые можно создать. Кадры типа 0x12 относятся к двухсторонним потокам, типа 0x13 – к односторонним. Формат кадров показан на рисунке 35.

   MAX_STREAMS Frame {
     Type (i) = 0x12..0x13,
     Maximum Streams (i),
   }

Рисунок 35. Формат кадра MAX_STREAMS.


Maximum Streams

Число потоков соответствующего типа, которые могут быть созданы в течение срока работы соединения. Это значение не может превышать 260, поскольку невозможно указать идентификатор потока больше 262-1. Приём кадра, разрешающего создать поток сверх заданного предела, должен считаться ошибкой соединения типа FRAME_ENCODING_ERROR.

Потери и нарушение порядка могут приводить к получению конечной точкой кадра MAX_STREAMS со значением меньше полученного ранее. Кадры MAX_STREAMS, не увеличивающие предел для потока, должны игнорироваться. Конечной точке недопустимо создавать больше потоков, чем указал партнёр. Например, сервер, получивший для односторонних потоков предел 3, может создать потоки 3, 7 и 11, но не 15. Конечная точка должна прерывать соединение с ошибкой STREAM_LIMIT_ERROR если партнёр превышает заданный предел с учётом нарушения запомненных пределов в Early Data (см. параграф 7.4.1). Отметим, что эти кадры (и соответствующие параметры транспорта) не задают число одновременных потоков. Принимаются во внимание открытые и закрытые потоки.

19.12. Кадр DATA_BLOCKED

Отправителю следует передать кадр DATA_BLOCKED (тип 0x14), когда он хочет передать данные, но управление потоком данных на уровне соединения не позволяет это (см. раздел 4). Кадры DATA_BLOCKED служат входными данными для настройки алгоритмов управления потоком данных (параграф 4.2). Формат кадра показан на рисунке 36.

   DATA_BLOCKED Frame {
     Type (i) = 0x14,
     Maximum Data (i),
   }

Рисунок 36. Формат кадра DATA_BLOCKED.


Maximum Data

Целое число переменного размера – ограничение на уровне соединения, при котором произошла блокировка.

19.13. Кадр STREAM_DATA_BLOCKED

Отправителю следует передать кадр STREAM_DATA_BLOCKED (тип 0x15), когда он хочет передать данные, но управление потоком данных на уровне потока не позволяет это. Этот тип кадров похож на DATA_BLOCKED (параграф 19.12). Конечная точка, получившая STREAM_DATA_BLOCKED для только передающего (send-only) потока, должна прервать соединение с ошибкой STREAM_STATE_ERROR. Формат кадра показан на рисунке 37.

   STREAM_DATA_BLOCKED Frame {
     Type (i) = 0x15,
     Stream ID (i),
     Maximum Stream Data (i),
   }

Рисунок 37. Формат кадра STREAM_DATA_BLOCKED.


Stream ID

Целое число переменного размера – идентификатор потока, заблокированного управлением потоком данных.

Maximum Stream Data

Целое число переменного размера – смещение потока, при котором произошла блокировка.

19.14. Кадр STREAMS_BLOCKED

Отправителю следует передать кадр STREAMS_BLOCKED (тип 0x16 или 0x17), когда он хочет создать поток, но заданное партнёром ограничение не позволяет это (см. параграф 19.11). Кадры типа 0x16 относятся к двухсторонним потокам, типа 0x17 – к односторонним. Кадр STREAMS_BLOCKED не создаёт поток, но информирует партнёра о потребности в новых потоках и достижении заданного им предела. Формат кадра показан на рисунке 38.

   STREAMS_BLOCKED Frame {
     Type (i) = 0x16..0x17,
     Maximum Streams (i),
   }

Рисунок 38. Формат кадра STREAMS_BLOCKED.


Maximum Streams

Целое число переменного размера, указывающее максимальное число потоков соответствующего типа на момент передачи кадра. Это значение не может превышать 260, поскольку невозможно указать идентификатор потока больше 262-1. Приём кадра, указывающего поток с большим номером, должен считаться ошибкой соединения типа STREAM_LIMIT_ERROR или FRAME_ENCODING_ERROR.

19.15. Кадр NEW_CONNECTION_ID

Конечная точка передаёт кадр NEW_CONNECTION_ID (тип 0x18) для предоставления партнёру дополнительных идентификаторов соединения, которые могут служить для предотвращения возможности сопоставлений при переносе соединения (см. параграф 9.5). Формат кадра NEW_CONNECTION_ID показан на рисунке 39.

Sequence Number

Целое число переменного размера – порядковый номер выделенный идентификатору соединения отправителем (параграф 5.1.1).

   NEW_CONNECTION_ID Frame {
     Type (i) = 0x18,
     Sequence Number (i),
     Retire Prior To (i),
     Length (8),
     Connection ID (8..160),
     Stateless Reset Token (128),
   }

Рисунок 39. Формат кадра NEW_CONNECTION_ID.


Retire Prior To

Целое число переменного размера – идентификаторы соединения, которые следует удалить (параграф 5.1.2).

Length

8-битовое целое число без знака, указывающее размер идентификатора соединения. Значения меньше 1 и больше 20 недействительны и должны считаться ошибкой соединения типа FRAME_ENCODING_ERROR.

Connection ID

Идентификатор соединения заданного размера.

Stateless Reset Token

128-битовое значение используемое для сброса без учёта состояния при использовании соответствующего идентификатора соединения (см. параграф 10.3).

Конечной точке недопустимо передавать этот кадр, если она в настоящее время требует от партнёра передачи пакетов с пустым Destination Connection ID. Замена пустого идентификатора соединения непустым и обратно осложняет определение момента смены идентификатора соединения. Конечная точка, передающая пакеты с пустым Destination Connection ID, должна считать получение кадра NEW_CONNECTION_ID ошибкой соединения типа PROTOCOL_VIOLATION.

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

При получении кадра NEW_CONNECTION_ID с ранее заданным идентификатором соединения, но с иным полем Stateless Reset Token, иным значением Sequence Number или порядковым номером, использованным для другого идентификатора соединения конечная точка может считать это ошибкой соединения типа PROTOCOL_VIOLATION.

Поле Retire Prior To применяется к идентификаторам, созданным в процессе организации соединения, и параметру транспорта preferred_address (см. параграф 5.1.2). Значение Retire Prior To должно быть не больше значения поля Sequence Number. Получение Retire Prior To больше Sequence Number должно считаться ошибкой соединения типа FRAME_ENCODING_ERROR. После того, как отправитель указал Retire Prior To, меньшие значения в последующих кадрах NEW_CONNECTION_ID не оказывают влияния. Получатель должен игнорировать поля Retire Prior To, не увеличивающие полученное ранее значение.

Конечная точка, получившая кадр NEW_CONNECTION_ID с порядковым номером меньше значения поля Retire Prior To в ранее полученном NEW_CONNECTION_ID должна передать соответствующий кадр RETIRE_CONNECTION_ID, удаляющий полученный недавно идентификатор соединения, если это ещё не сделано для порядкового номера.

19.16. Кадр RETIRE_CONNECTION_ID

Конечная точка передаёт кадр RETIRE_CONNECTION_ID (тип 0x19) для указания того, что она больше не будет применять идентификатор соединения, выданный партнёром. Это включает идентификаторы, представленные во время согласования. передача RETIRE_CONNECTION_ID служит также запросом к партнёру на передачу дополнительных идентификаторов соединения на будущее (см. параграф 5.1). Новые идентификаторы могут быть доставлены в кадрах NEW_CONNECTION_ID (параграф 19.15). Удаление идентификатора соединения делает недействительным связанный с ним маркер сброса без учёта состояния. Формат кадра показан на рисунке 40.

   RETIRE_CONNECTION_ID Frame {
     Type (i) = 0x19,
     Sequence Number (i),
   }

Рисунок 40. Формат кадра RETIRE_CONNECTION_ID.


Sequence Number

Порядковый номер удаляемого идентификатора соединения (см. параграф 5.1.2).

Получение кадра RETIRE_CONNECTION_ID с порядковым номером больше переданных ранее партнёру должно считаться ошибкой соединения типа PROTOCOL_VIOLATION.

Порядковому номеру в кадре RETIRE_CONNECTION_ID недопустимо указывать поле Destination Connection ID в пакете, где содержится кадр. Партнер может считать это ошибкой соединения типа PROTOCOL_VIOLATION.

Конечная точка не может передавать этот кадр, если партнёр предоставил пустой идентификатор соединения. Конечная точка, предоставившая пустой идентификатор соединения, должна считать получение кадра RETIRE_CONNECTION_ID ошибкой соединения типа PROTOCOL_VIOLATION.

19.17. Кадр PATH_CHALLENGE

   PATH_CHALLENGE Frame {
     Type (i) = 0x1a,
     Data (64),
   }

Рисунок 41. Формат кадра PATH_CHALLENGE.


Конечная точка может использовать кадры PATH_CHALLENGE (тип 0x1a) для проверки доступности партнёра и проверки пути при переносе соединения. Формат кадра PATH_CHALLENGE показан на рисунке 41.

Data

8-битовое поле с произвольными данными.

Включение 64 битов энтропии в кадр PATH_CHALLENGE гарантирует, что легче принять кадр, чем угадать значение. Получатель кадра должен генерировать кадр PATH_RESPONSE (параграф 19.18) с тем же значением в поле Data.

19.18. Кадр PATH_RESPONSE

Кадр PATH_RESPONSE (тип 0x1b) передаётся в ответ на PATH_CHALLENGE. Формат кадра показан на рисунке 42.

   PATH_RESPONSE Frame {
     Type (i) = 0x1b,
     Data (64),
   }

Рисунок 42. Формат кадра PATH_RESPONSE.


Если содержимое кадра PATH_RESPONSE не соответствует ранее переданному PATH_CHALLENGE конечная точка может считать это ошибкой соединения типа PROTOCOL_VIOLATION.

19.19. Кадр CONNECTION_CLOSE

Конечная точка передаёт кадр CONNECTION_CLOSE (тип 0x1c или 0x1d) для уведомления партнёра о закрытии соединения. Кадр типа 0x1c используется для сигнализации об ошибках лишь на уровне QUIC или отсутствии ошибок (код NO_ERROR), а типа 0x1d – для сигнализации об ошибках приложения, использующего QUIC. При наличии потоков, не закрытых явно, они будут неявно закрыты при завершении соединения. Формат кадра показан на рисунке 43.

   CONNECTION_CLOSE Frame {
     Type (i) = 0x1c..0x1d,
     Error Code (i),
     [Frame Type (i)],
     Reason Phrase Length (i),
     Reason Phrase (..),
   }

Рисунок 43. Формат кадра CONNECTION_CLOSE.


Error Code

Целое число переменного размера – код причины закрытия соединения. CONNECTION_CLOSE типа 0x1c использует коды из пространства, определённого в параграфе 20.1, CONNECTION_CLOSE типа 0x1d – определённые прикладным протоколом (см. параграф 20.2).

Frame Type

Целое число переменного размера – тип вызвавшего ошибку кадра. Значение 0 (эквивалентное указанию кадра PADDING) служит для неизвестных типов кадров. Определяемый приложением кадр CONNECTION_CLOSE (тип 0x1d) не использует это поле.

Reason Phrase Length

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

Reason Phrase

Диагностические сведения о причине закрытия. Поле может быть пустым, если отправитель счёл нужным предоставить лишь значение Error Code. В поле следует указывать строку в кодировке UTF-8, хотя в кадре нет информации (такой, как тег языка).

Определяемый приложением вариант CONNECTION_CLOSE (тип 0x1d) может передаваться лишь в кадрах 0-RTT или 1-RTT (см. параграф 12.5). При желании приложения прервать соединение в процессе согласования конечная точка может передать CONNECTION_CLOSE типа 0x1c с кодом APPLICATION_ERROR в пакете Initial или Handshake.

19.20. Кадр HANDSHAKE_DONE

Сервер использует кадр HANDSHAKE_DONE (тип 0x1e) для подтверждения согласования клиенту. Кадр HANDSHAKE_DONE не имеет содержимого, как показано на рисунке 44.

   HANDSHAKE_DONE Frame {
     Type (i) = 0x1e,
   }

Рисунок 44. Формат кадра HANDSHAKE_DONE.


Кадр HANDSHAKE_DONE может передавать только сервер. Серверам недопустимо передавать HANDSHAKE_DONE до завершения согласования. Приём кадра HANDSHAKE_DONE сервером должен считаться ошибкой соединения типа PROTOCOL_VIOLATION.

19.21. Кадры расширения

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

Расширения, меняющие или замещающие базовую функциональность протокола (включая типы кадров), сложно объединить с другими расширениями, которые меняют или замещают те же функции, пока поведение такой комбинации не задано явно. Таким расширениям следует определять их взаимодействие с другими расширениями, меняющими те же компоненты протокола. Для кадров расширения должен обеспечиваться контроль перегрузки и они должны вызывать передачу кадров ACK. Исключением являются расширения кадров, дополняющие или заменяющие кадры ACK. Кадры расширения не включаются в управление потоком данных, пока они не указаны в расширении.

Для управления назначением новых типов кадров служит реестр IANA, описанный в параграфе 22.4.

20. Коды ошибок

Коды транспортных ошибок QUIC и ошибок приложение представляются 62-битовыми целыми числами без знака.

20.1. Коды транспортных ошибок

В этом разделе приведён список ошибок транспорта QUIC, которые могут указываться в кадрах CONNECTION_CLOSE типа 0x1c. Эти ошибки относятся к соединению в целом.

NO_ERROR (0x00)

Конечная точка использует этот код с CONNECTION_CLOSE для информирования о внезапном закрытии соединения без ошибок.

INTERNAL_ERROR (0x01)

Внутренняя ошибка конечной точки, препятствующая работе соединения.

CONNECTION_REFUSED (0x02)

Сервер отверг новое соединение.

FLOW_CONTROL_ERROR (0x03)

Конечная точка получила больше данных, чем задано анонсированным пределом (см. раздел 4).

STREAM_LIMIT_ERROR (0x04)

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

STREAM_STATE_ERROR (0x05)

Конечная точка получила кадр для потока, находящегося в состоянии, для которого такой кадр не разрешён (см. раздел 3).

FINAL_SIZE_ERROR (0x06)

(1) Конечная точка получила кадр STREAM с данными, выходящими за пределы ранее согласованного общего размера. (2) Конечная точка получила кадр STREAM или RESET_STREAM, содержащий общий размер, который меньше объёма уде принятых в потоке данных. (3) Конечная точка получила кадр STREAM или RESET_STREAM, содержащий общий размер данных, отличающийся от уже согласованного.

FRAME_ENCODING_ERROR (0x07)

Конечная точка получила кадр с ошибкой формата, например, кадр неизвестного типа или кадр ACK, в котором диапазон подтверждения больше, нежели может перенести остальная часть пакета.

TRANSPORT_PARAMETER_ERROR (0x08)

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

CONNECTION_ID_LIMIT_ERROR (0x09)

Число представленных партнёром идентификаторов соединения превышает анонсированное значение active_connection_id_limit.

PROTOCOL_VIOLATION (0x0a)

Конечная точка обнаружила протокольную ошибку, для которой не задано кода.

INVALID_TOKEN (0x0b)

Сервер получил от клиента пакет Initial с недействительным полем Token.

APPLICATION_ERROR (0x0c)

Закрытие соединения, вызванное приложением или прикладным протоколом.

CRYPTO_BUFFER_EXCEEDED (0x0d)

Конечная точка получила в кадрах CRYPTO объем данных, который она не может буферизовать.

KEY_UPDATE_ERROR (0x0e)

Конечная точка обнаружила ошибку при обновлении ключей (см. раздел 6 в [QUIC-TLS]).

AEAD_LIMIT_REACHED (0x0f)

Конечная точка достигла предела защиты конфиденциальности или целостности используемого в соединении алгоритма AEAD.

NO_VIABLE_PATH (0x10)

Конечная точка определила, что путь через сеть не может поддерживать QUIC. Получение конечной точкой кадра CONNECTION_CLOSE с таким кодом маловероятно за исключением случая, когда путь не имеет достаточного MTU.

CRYPTO_ERROR (0x0100-0x01ff)

Отказ при криптографическом согласовании. Диапазон из 256 значений зарезервирован для кодов ошибок используемого криптографического согласования. Коды ошибок при криптографическом согласовании TLS приведены а параграфе [QUIC-TLS].

Регистрация новых кодов ошибок рассмотрена в параграфе 22.5.

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

20.2. Коды ошибок прикладного протокола

Поддержка кодов ошибок прикладного протокола оставлена этим протоколам. Коды ошибок прикладного протокола используются в кадрах RESET_STREAM (параграф 19.4), STOP_SENDING (параграф 19.5) и CONNECTION_CLOSE типа 0x1d (параграф 19.19).

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

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

21.1. Обзор защитных свойств

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

QUIC предполагает модель угроз, описанную в [SEC-CONS], и обеспечивает защиту от соответствующих модели атак. Атаки делятся на активные и пассивные. В пассивных атаках у злоумышленников имеется возможность считывать пакеты из сети, а в активных им доступна также запись. Однако в пассивной атаке может участвовать злоумышленник, способный менять маршрутизацию или иначе влиять на пути прохождения пакетов, составляющих соединение.

Атакующие делятся на размещённых в пути доставки пакетов и вне этого пути. Расположенные на пути злоумышленники могут читать, изменять или удалять любой наблюдаемый пакет так, что он не достигнет адресата. Атакующие извне пути могут наблюдать пакеты, но не способны воспрепятствовать их доставке. Оба типа атакующих могут также передавать произвольные пакеты. Эта классификация отличается от принятой в параграфе 3.5 [SEC-CONS] тем, что находящийся вне пути злоумышленник может наблюдать пакеты.

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

21.1.1. Согласование

Согласование QUIC (handshake) включает согласование TLS 1.3 и наследует криптографические свойства, описанные в Приложении E.1 к [TLS13]. Многие из свойств защиты QUIC зависят от согласования TLS, обеспечивающего эти свойства. Любая атака на TLS может влиять на QUIC.

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

Атака на целостность согласования TLS может позволить злоумышленнику повлиять на выбор прикладного протокола или версии QUIC.

В дополнение к предоставляемым TLS свойствам согласование QUIC обеспечивает некоторую защиту от DoS-атак на согласование.

21.1.1.1. Антиусиление

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

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

21.1.1.2. DoS на стороне сервера

Расчёт первой отправки с сервера для полного согласования может быть затратным, включая расчёт подписи и обмен ключами. Для предотвращения DoS-атак, потребляющих ресурсы сервера, пакеты Retry обеспечивают недорогой механизм обмена маркерами, позволяющий серверу проверить IP-адрес клиента до выполнения затратных расчётов за счёт одного дополнительного кругового обхода. После успешного согласования серев может выпустить для клиента новые маркеры, позволяющие тому организовать новое соединение без дополнительных издержек.

21.1.1.3. Прерывание согласования в пути

Злоумышленник на пути или вне его может вызвать отказ согласования, подменив или разогнав пакеты Initial. После обмена действительными пакетами Initial последующие пакеты Handshake защищаются ключами Handshake и находящийся на пути злоумышленник не может вызвать сбой согласования иной, нежели отбрасывание пакетов, вынуждающее прекратить попытку. Такой атакующий может также заменить адреса в пакетах любой из сторон, вынуждая клиента или сервер видеть некорректный адрес удалённой точки. Такая атака неотличима от преобразований NAT.

21.1.1.4. Согласование параметров

Согласование целиком защищено криптографически, причём пакеты Initial шифруются зависящими от версии ключами, а Handshake и последующие пакеты – ключами, выведенными из обмена TLS. Кроме того, согласование параметров охватывается TLS и для него обеспечивается защита целостности как для обычного согласования TLS. Атакующий может видеть транспортные параметры клиента (если известна зависимая от версии затравка), но не может видеть транспортных параметров сервера и влиять на согласование параметров.

Идентификаторы соединений не шифруются, но охватываются защитой целостности во всех пакетах.

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

21.1.2. Защищённые пакеты

Для защиты пакетов (параграф 12.1) применяется аутентифицированное шифрование всех пакетов, кроме Version Negotiation, хотя пакеты Initial и Retry имеют ограниченную защиту по причине использования зависимого от версии ключевого материала (см. [QUIC-TLS]). В этом параграфе рассмотрены пассивные и активные атаки на защищённые пакеты.

Атакующие на пути и вне его могут организовать пассивную атаку с сохранением наблюдаемых пакетов для последующего взлома защиты. Это возможно для любого наблюдателя любого пакета в сети.

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

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

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

21.1.3. Перенос соединения

Перенос соединения (раздел 9) позволяет конечным точка менять IP-адреса и порты на нескольких путях, используя в каждый момент один путь для передачи и приёма кадров, не являющихся зондами. Проверка пути (параграф 8.2) устанавливает, что партнёр хочет и может принимать пакеты, переданные по конкретному пути. Это помогает снизить влияние фиктивных адресов путём ограничения числа пакетов, передаваемых по такому адресу. В этом параграфе рассмотрены свойства защиты от разных типов DoS-атак при переносе соединения.

21.1.3.1. Активные атаки в пути

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

  • просматривать пакеты;

  • изменять заголовки IP и UDP;

  • внедрять свои пакеты;

  • задерживать пакеты;

  • менять порядок пакетов;

  • отбрасывать пакеты;

  • расщеплять и объединять дейтаграммы по границам пакетов.

Однако он не может менять аутентифицируемые части пакетов так, чтобы получатель воспринял пакет.

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

QUIC пытается ограничить возможности расположенного на пути злоумышленника несколькими способами.

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

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

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

  4. Злоумышленник может снизить пропускную способность, задерживая или отбрасывая пакеты.

  5. Атакующие не может заставить конечную точку воспринимать пакеты, в которых он изменил аутентифицируемую часть.

21.1.3.2. Активные атаки извне пути

Злоумышленник вне пути не находится непосредственно на пути между клиентом и сервером, но может получать копии всех или части пакетов, передаваемых между ними, а также передавать копии этих пакетов любой из конечных точек. Атакующий может:

  • просматривать пакеты;

  • внедрять новые пакеты;

  • менять порядок внедряемых пакетов.

Атакующий не способен:

  • менять переданные конечными точками пакеты;

  • задерживать пакеты;

  • отбрасывать пакеты;

  • менять порядок исходных пакетов.

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

  1. Атакующий может «разгонять» пакеты и пытаться стать «ограниченным» злоумышленником на пути.

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

  3. Злоумышленник не может закрыть соединение после завершения согласования.

  4. Злоумышленник не может вызвать перенос соединения на новый путь, если он не может наблюдать этот путь.

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

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

21.1.3.3. Ограниченные активные атаки на пути

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

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

Ограниченный атакующий на пути может:

  • просматривать пакеты;

  • внедрять свои пакеты;

  • менять нешифрованные заголовки пакетов;

  • изменять порядок пакетов.

Однако такой злоумышленник не способен:

  • задерживать пакеты так, чтобы они приходили позже пакетов по исходному пути;

  • отбрасывать пакеты;

  • менять аутентифицированные и шифрованные части пакета, заставляя получателя воспринимать их.

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

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

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

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

Отметим, что такие же гарантии обеспечиваются для любого NAT по тем же причинам.

21.2. DoS-атаки на согласование

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

После организации соединения конечные точки QUIC могут воспринимать некоторые неаутентифицированные пакеты ICMP (см. параграф 14.2.1), но использование таких пакетов очень ограничено. Единственный другой тип пакета, воспринимаемый конечной точкой, – это пакет сброса без учёта состояния (параграф 10.3), в котором используется маркер, сохраняемый в секрете до его применения.

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

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

Поля Source Connection ID и Destination Connection ID служат основным средством защиты от атак извне пути в процессе согласования (см. параграф 8.1). Они должны соответствовать установленным партнёром значениям. За исключением Initial и Stateless Resets, конечная точка воспринимает лишь пакеты с полем Destination Connection ID, соответствующим значению, которое конечная точка выбрала раньше. Это единственная защита для пакетов Version Negotiation.

Поле Destination Connection ID в пакете Initial клиент выбирает как непредсказуемое, что служит дополнительной цели. Пакеты криптографического согласования защищены с использованием ключа, выведенного из этого идентификатора соединения и затравки, определяемой версией QUIC. Это позволяет конечной точке использовать один процесс для аутентификации получаемых пакетов в процессе и по завершении криптографического согласования. Не прошедшие аутентификацию пакеты отбрасываются. Такая защита пакетов обеспечивает уверенность в том, что отправитель пакета видел пакет Initial и понял его.

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

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

21.3. Атаки с усилением

Атакующий может получить маркер проверки адреса (раздел 8) от сервера, а затем освободить использованный для этого адрес IP. Позднее он может инициировать соединение 0-RTT с сервером, подставив тот же адрес, который фактически может принадлежать другой конечной точке (жертве). После этого атакующий потенциально может вынудить сервер передать этой жертве данные в размере начального окна перегрузки. Серверам следует обеспечивать смягчение таких атак, ограничивая срок действия маркеров проверки адреса (см. параграф 8.1.3).

21.4. Атаки с избыточными подтверждениями

Конечная точка, подтверждающая непринятые пакеты, может заставит контроллер перегрузок разрешить передачу со скоростью, превосходящей возможности сети. Конечная точка может пропускать номера для передаваемых пакетов с целью обнаружить такое поведение. Затем конечная точка может немедленно закрыть соединение с ошибкой типа PROTOCOL_VIOLATION (см. параграф 10.2).

21.5. Атаки с подменой запросов

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

Для эффективной подделки запросов атакующему нужна возможность влиять на то, какие пакеты и куда отправляет партнёр. Если злоумышленник может нацелить уязвимую службу с контролируемым содержимым (payload), эта служба может выполнить действия, которые невольный атакующий выполнит для злоумышленника. Например, подделка межсайтовых запросов [CSRF] в Web заставляет клиента выдавать запросы, включающие cookie проверки полномочий [COOKIE], что открывает одному сайту доступ к информации и действиям, разрешённым для другого сайта.

Поскольку QUIC работает по протоколу UDP, основная проблема атак заключается в том, что злоумышленник может выбрать адрес, на который его партнёр будет передавать дейтаграммы UDP, и контролировать незащищённое содержимое пакетов. Поскольку большая часть данных, отправляемых конечными точками QUIC, защищена, это включает контроль над шифрованными данными. Атака будет успешной, если злоумышленник может вынудить партнёра передать дейтаграмму UDP хосту, который выполнит некое действие в зависимости от содержимого дейтаграммы.

В этом параграфе описаны возможные способы использования QUIC для атак с поддельными запросами. Описаны также ограниченные меры противодействия, которые могут быть реализованы конечными точками QUIC. Эти меры ослабления могут применяться в одностороннем порядке реализацией или развёртыванием QUIC без принятия каких-либо мер у потенциальных жертв. Однако этих мер может быть недостаточно, если службы на основе UD не проверяют полномочия должным образом.

Поскольку атака с переносом, описанная в параграфе 21.5.4, является достаточно мощное и для неё нет достаточных мер противодействия, реализациям серверов QUIC следует предполагать, что злоумышленники могут заставить их генерировать произвольное содержимое UDP для произвольных получателей. Серверы QUIC не следует развёртывать в сети без фильтрации на входе [BCP38] и с конечными точками UDP без адекватной защиты.

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

21.5.1. Возможности управления для конечных точек

QUIC открывает для злоумышленников некоторые возможности влияния на отправку партнёром дейтаграмм UDP:

  • при организации соединения (раздел 7) сервер может указать, куда клиенту следует передавать дейтаграммы (например, путём заполнения записей DNS);

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

  • с помощью фиктивного переноса соединения (параграф 9.3.1) клиент может использовать обмену адреса отправителя для выбора адреса, по которому сервер будет передавать последующие дейтаграммы;

  • обманные пакеты могут вынудить сервер передать пакет Version Negotiation (параграф 21.5.5).

Во всех перечисленных случаях злоумышленник может вынудить партнёра передавать дейтаграммы жертве, которая может не понимать QUIC, т. е. пакеты будут передаваться до проверки адреса (см. раздел 8).

За пределами защищённой части пакета QUIC предоставляет конечной точке несколько возможностей управления содержимым дейтаграмм UDP, передаваемых партнёром. Поле Destination Connection ID предоставляет прямой контроль над байтами в ранних пакетах, передаваемых партнёром (см. параграф 5.1). Поле Token в пакетах Initial открывает серверу контроль над другими байтами в пакетах Initial (см. параграф 17.2.2).

В данной версии QUIC нет мер предотвращения косвенного контроля над защищёнными частями пакетов. Необходимо учитывать возможность конечной точки контролировать содержимое кадров, передаваемых партнёром, особенно для кадров с данными приложения, таких как STREAM. Хотя это в некоторой степени зависит от прикладного протокола, во многих вариантах использования протоколов некоторый контроль возможен. Когда у злоумышленника есть доступ к ключам защиты пакетов, он вероятно сможет угадать, как партнёр будет шифровать последующие пакеты. Для успешного контроля над содержимым дейтаграмм атакующему нужна лишь возможность предсказать номер пакета и размещение кадров в пакете с той или иной достоверностью.

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

21.5.2. Обманный запрос в клиентских пакетах Initial

Злоумышленник, действующий как сервер, может выбрать IP-адрес и порт, для которых он анонсирует свою доступность, поэтому пакеты Initial от клиента считаются доступными для использования в этом типе атак. Неявная проверка адреса в согласовании (handshake) гарантирует для нового соединения, что клиент не будет передавать другие типы пакетов адресату, которые не понимает QUIC или не желает воспринимать соединения QUIC.

Защита пакетов Initial (параграф 5.2 в [QUIC-TLS]) осложняет для серверов контроль над содержимым пакетов Initial, передаваемых клиентами. Выбор клиентом непредсказуемого значения Destination Connection ID не позволяет серверам контролировать какую-либо шифрованную часть пакетов Initial от клиента. Однако поле Token открыто для сервера и позволяет ему использовать клиентов для организации атак с обманными запросами. Использование маркеров, передаваемых в кадрах NEW_TOKEN (параграф 8.1.3) открывает лишь возможность подделки запроса в процессе организации соединения. Однако клиенты не обязаны использовать кадр NEW_TOKEN. Атаки с поддельными запросами на основе поля Token можно предотвратить, если клиенты передают пустое поле Token при изменении адреса сервера с момента получения кадра NEW_TOKEN. Клиенты могут избегать применения NEW_TOKEN, если адрес сервера изменился. Однако исключение поля Token может негативно влиять на производительность. Серверы могут на основе поля NEW_TOKEN разрешать передачу данных в объёме, превышающем утроенный объем принятых данных (см. параграф 8.1). В частности, это влияет на запросы клиентом дополнительных данных от сервера с использованием 0-RTT.

Передача пакета Retry (параграф 17.2.5) позволяет серверу изменить поле Token. После отправки Retry сервер может также контролировать поле Destination Connection ID в последующих пакетах Initial от клиента. Это также может открыть опосредованный контроль над шифрованным содержимым пакетов Initial. Однако передача Retry подтверждает адрес сервера, предотвращая тем самым использование последующих пакетов Initial для обманных запросов.

21.5.3. Обманный запрос с предпочтительным адресов

Серверы могут указывать предпочтительный адрес, на который клиенты переходят после подтверждения согласования (см. параграф 9.6). Поле Destination Connection ID в пакетах от клиента по предпочтительному адресу можно использовать для обманных запросов. Клиенту недопустимо передавать не являющиеся зондами кадры по предпочтительному адресу до его проверки (см. раздел 8). Это существенно снижает возможности контроля сервера над шифрованными частями дейтаграмм. Этот документ не предлагает дополнительных мер противодействия, связанных с использованием предпочтительных адресов, которые могут быть реализованы конечными точками. Базовые меры из параграфа 21.5.6 могут служить для смягчения атак.

21.5.4. Обманный запрос с фиктивным переносом

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

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

Этот документ не предлагает дополнительных мер противодействия, которые могут быть реализованы конечными точками, сверх описанных в параграфе 21.5.6. Однако меры предотвращения подмены адресов на сетевом уровне (в частности, фильтрация на входе [BCP38]) обеспечивают защиту от атак с подменой адресов из внешней сети.

21.5.5. Обманный запрос с Version Negotiation

Клиенты, способные предоставить фиктивный адрес отправителя, могут вынудить сервер передать по этому адресу пакет Version Negotiation (параграф 17.2.1). Отсутствие ограничения размера идентификатора соединения в пакетах неизвестной версии увеличивает объем данных, контролируемых клиентом в дейтаграммах. Первый байт пакета не находится под контролем клиента, а следующие 4 байта содержат нули, но клиент может контролировать 512 байтов, начиная с пятого. Для противодействия таким атакам нет мер, сверх указанных в параграфе параграф 21.5.6. Фильтрация на входе [BCP38] будет работать.

21.5.6. Базовые меры противодействия обманным запросам

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

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

Конечные точки могут считать замену адреса на link-local [RFC4291] или адрес из частного диапазона [RFC1918] вместо глобального, уникального локально [RFC4193] или публичного (non-private) адреса как возможную попытку обманного запроса. Конечные точки могут полностью отказаться от использования таких адресов, но это связано с риском нарушения легитимных вариантов работы. Конечным точкам не следует использовать адрес, пока нет конкретных сведений о сети, указывающих, что передача дейтаграмм по непроверенным адресам из данного диапазона безопасна.

Конечные точки могут снизить риск обманных запросов, не включая значений из кадров NEW_TOKEN в пакеты Initial или передавая лишь пробные пакеты до завершения проверки адреса. Отметим, что это не препятствует использованию для атак поля Destination Connection ID.

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

Примечание. Изменение конечных точек для применения этих средств защиты более эффективно, чем развёртывание сетевых средств защиты, поскольку от конечных точек не требуется выполнение дополнительной обработки при передаче по непроверенным адресам.

21.6. Slowloris-атаки

Атаки, обычно называемые Slowloris [SLOWLORIS], пытаются сохранить множество открытых соединений с целевой конечной точкой как можно дольше. Такие атаки могут быть нацелены на конечную точку QUIC с минимальной активностью, требуемой для сохранения соединения. Это может быть передача небольших объёмов данных, постепенное открытие окон управления потоком данных для управления скоростью передачи или создание кадров ACK, имитирующих высокую скорость потерь. При развёртывании QUIC следует обеспечивать смягчение Slowloris-атак такими способами, как увеличение максимального числа клиентов, поддерживаемого сервером, ограничение числа соединений с одного адреса IP, ограничение на минимальную скорость обмена данные в соединении, ограничение продолжительности соединений по времени.

21.7. Атаки с фрагментацией и сборкой пакетов

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

Атаки на получателей ослабляются, если окно управления потоком данных соответствует доступной памяти. Однако некоторые получатели будут чрезмерно использовать память и анонсировать смещения управления потоком данных, суммарно превосходящие размер доступной памяти. Стратегия выделения избыточной памяти может повышать производительность при корректном поведении конечной точки, но делает такую точку уязвимой для атак с фрагментацией потока. При развёртывании QUIC следует обеспечивать смягчение атак с фрагментацией потоков. Это может быть предотвращение выделения избыточной памяти, задержка сборки кадров STREAM, реализация эвристики на основе продолжительности пропусков в сборке и комбинации этих методов.

21.8. Атака с представлением потоков

Злонамеренная конечная точка может создать большое число потоков, исчерпав состояния партнёра, а также повторять процесс для организации большого числа соединения в стиле атак SYN flood на протокол TCP. Обычно клиенты создают потоки последовательно, как описано в параграфе 2.1. Однако при запуске нескольких потоков с короткими интервалами потеря или нарушение порядка могут вызвать нарушение порядка доставки кадров STREAM. На приёмной стороне при получении потока с большим номером получатель должен создать все промежуточные потоки того же типа (см. параграф 3.2). таким образом, в новом соединении создание потока 4000000 приведёт к созданию миллиона и одного инициированного клиентом двухстороннего потока. Число активных потоков ограничено транспортными параметрами initial_max_streams_bidi и initial_max_streams_uni, которые обновляются любыми принятыми кадрами MAX_STREAMS, как описано в параграфе 4.6. При разумном выборе эти ограничения смягчают атаки с представлением потока, однако установка слишком низкого предела может повлиять на производительность приложений, ожидающих большого числа потоков.

21.9. DoS-атаки на партнёров

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

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

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

21.10. Атаки с явной индикацией перегрузки

Атакующий на пути может менять значения ECN в заголовке IP для воздействия на скорость передачи. В [RFC3168] рассмотрены такие манипуляции и их влияние. Ограниченный атакующий на пути может дублировать и передавать пакеты с изменёнными полями ECN для влияния на скорость передачи. Если дубликаты пакетов получатель отбрасывает, атакующему придётся состязаться с исходными пакетами для успешной атаки. Поэтому конечные точки QUIC игнорируют поле ECN в пакетах IP, если не будет успешно обработан хотя бы один пакет QUIC в этом пакете IP (см. параграф 13.4).

21.11. Предсказание Stateless Reset

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

Если пакет может быть направлен в разные экземпляры с общим статическим ключом, например, путём смены IP-адреса или порта, злоумышленник может вынудить сервер передать сброс без учёта состояния. Для защиты от такой атаки конечные точки, имеющие общий ключ для сброса без учёта состояния (см. параграф 10.3.2), должны быть организованы так, чтобы пакеты с данным идентификатором соединения всегда поступали экземпляру, имеющему статус соединения, если только это соединение не утратило активность.

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

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

21.12. Понижение версии

В этом документе определены пакеты QUIC Version Negotiation (раздел 6), служащие для согласования версии QUIC между парой конечных точек. Однако документ не задаёт способ согласования данной версии с будущими. В частности, пакеты Version Negotiation не включают механизма предотвращения атак на понижение версии. Будущие версии QUIC при использовании пакетов Version Negotiation должны задать механизм, устойчивый к таким атакам.

21.13. Нацеливание атак через маршрутизацию

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

21.14. Анализ трафика

Размер пакетов QUIC может раскрывать сведения о размере их содержимого. Кадры PADDING позволяют конечным точкам возможность скрыть размер содержимого пакетов (см. параграф 19.1).

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

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

Этот документ создаёт несколько реестров для поддержки кодов, применяемых в QUIC и управляемых одним набором правил, описанных в параграфе 22.1.

22.1. Правила регистрации для реестров QUIC

Во всех реестрах QUIC возможна предварительная и постоянная регистрация кодов в соответствии с приведёнными ниже правилами.

22.1.1. Предварительная регистрация

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

Предварительная регистрация выполняется по процедуре Expert Review, описанной в параграфе 4.5 [RFC8126]. Назначенным экспертам рекомендуется отвергать лишь регистрации, запрашивающие слишком большую часть оставшегося пространства или первое невыделенное значение (см. параграф 22.1.2). Предварительная регистрация включат поле Date, указывающее дату последнего обновления регистрации. Запрос на обновление предварительной регистрации можно сделать без рецензии назначенных экспертов.

Все реестры QUIC включают указанные ниже поля для поддержки предварительной регистрации.

Value

Назначенный код.

Status

Постоянная (permanent) или предварительная (provisional) регистрация.

Specification

Ссылка на доступную публично спецификацию значения.

Date

дата последнего обновления регистрации.

Change Controller

Субъект, ответственный за определение регистрации.

Contact

Контактные данные регистрирующего лица.

Notes

Дополнительные примечания для регистрации.

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

22.1.2. Выбор кодов

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

Первый невыделенный код резервируется для назначения по процедуре Standards Action (см. параграф 4.9 в [RFC8126]). Для таких значения можно использовать процесс раннего назначения [EARLY-ASSIGN]. Для кодов, представляемых целыми числами переменного размера (раздел 16), таких как типы кадров, следует использовать коды, представляемые 4 или 8 байтами (значение 214 и выше), если применение не зависит существенно от размера кодирования.

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

22.1.3. Повторное заявление предварительных кодов

Может быть подан запрос на удаление неиспользованных кодов с предварительной регистрацией для освобождения пространства в реестре или части реестра (например, из диапазона 64-16383 с кодами переменного размера). Это следует применять лишь для кодой с наиболее ранней датой регистрации, а записи, обновлённые менее чем за год до события, не следует заявлять повторно.

Запрос на удаление кода должен рассматриваться назначенными экспертами. Эксперты должны попытаться определить, используется ли удаляемый код. Экспертам рекомендуется связаться с указанными при регистрации контактными лицами, а также с как можно более широким кругом разработчиков протокола для получения сведений о применении кода. Экспертам рекомендуется ждать откликов не менее 4 недель.

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

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

22.1.4. Постоянная регистрация

Для постоянной регистрации в реестрах QUIC применяется процедура Specification Required (параграф 4.6 в [RFC8126]), если не указано иное. Назначенные эксперты проверяют наличие и доступность спецификаций. Экспертам рекомендуется быть беспристрастными, одобряя регистрации, если те не являются оскорбительными, легкомысленными или вредоносными (не просто неприятными эстетически или сомнительными архитектурно). При создании реестра могут задаваться дополнительные ограничения для постоянных регистраций.

При создании реестра могут указываться диапазоны кодов, для которых регистрация выполняется по особым правилам. Например, в реестре QUIC Frame Types (параграф 22.4) применяется более строгий подход для кодов из диапазона 0 – 63. Любые более строгие требования к постоянной регистрации не препятствуют предварительной регистрации соответствующих кодов. Например, можно запросить предварительную регистрацию кода типа кадра 61.

Все регистрации в документах Standards Track должны быть постоянными. Всем регистрациям этого документа выделен статус постоянных и список меняет контролёр IETF в контакте с рабочей группой QUIC (quic@ietf.org).

22.2. Реестр версий QUIC

Агентство IANA создало реестр QUIC Versions в разделе QUIC. Реестр QUIC Versions управляет 32-битовым пространством значений (см. раздел 15). Правила регистрации указаны в параграфе 22.1. Постоянная регистрация в этом реестре выполняется по процедуре Specification Required (параграф 4.6 в [RFC8126]).

Код 0x00000001 выделен с постоянным статусом для протокола, описанного в этом документе. Код 0x00000000 задан как постоянный резерв и указывает, что номер версии зарезервирован для согласования версий. Коды, соответствующие шаблону 0x?a?a?a?a являются резервными и IANA недопустимо выделять их, а также недопустимо указывать в списке выделенных значений.

22.3. Реестр транспортных параметров QUIC

Агентство IANA создало реестр QUIC Transport Parameters в разделе QUIC. Реестр QUIC Transport Parameters управляет 62-битовым пространством значений. Правила регистрации указаны в параграфе 22.1. Постоянная регистрация в этом реестре выполняется по процедуре Specification Required (параграф 4.6 в [RFC8126]), за исключением диапазона 0x00 – 0x3f (включительно), где применяется процедура Standards Action или IESG Approval в соответствии с параграфом 4.9 или 4.10 в [RFC8126].

В дополнение к полям, указанным в параграфе 22.1.1, для постоянной регистрации в этом реестре должно указываться поле Parameter Name с кратким мнемоническим обозначением параметра. Исходное содержимое реестра приведено в таблице 6.

Таблица 6. Исходное содержимое реестра параметров транспорта.

Значение

Имя параметра

Документ

0x00

original_destination_connection_id

Параграф 18.2

0x01

max_idle_timeout

Параграф 18.2

0x02

stateless_reset_token

Параграф 18.2

0x03

max_udp_payload_size

Параграф 18.2

0x04

initial_max_data

Параграф 18.2

0x05

initial_max_stream_data_bidi_local

Параграф 18.2

0x06

initial_max_stream_data_bidi_remote

Параграф 18.2

0x07

initial_max_stream_data_uni

Параграф 18.2

0x08

initial_max_streams_bidi

Параграф 18.2

0x09

initial_max_streams_uni

Параграф 18.2

0x0a

ack_delay_exponent

Параграф 18.2

0x0b

max_ack_delay

Параграф 18.2

0x0c

disable_active_migration

Параграф 18.2

0x0d

preferred_address

Параграф 18.2

0x0e

active_connection_id_limit

Параграф 18.2

0x0f

initial_source_connection_id

Параграф 18.2

0x10

retry_source_connection_id

Параграф 18.2

Значения вида 31*N+27 для целых N (т. е. 27, 58, 89 …) являются резервным и их недопустимо выделять IANA и недопустимо включать в список выделенных значений.

22.4. Реестр типов кадров QUIC

Агентство IANA создало реестр QUIC Frame Types в разделе QUIC. Реестр QUIC Frame Types управляет 62-битовым пространством значений. Правила регистрации указаны в параграфе 22.1. Постоянная регистрация в этом реестре выполняется по процедуре Specification Required (параграф 4.6 в [RFC8126]), за исключением диапазона 0x00 – 0x3f (включительно), где применяется процедура Standards Action или IESG Approval в соответствии с параграфом 4.9 или 4.10 в [RFC8126].

В дополнение к полям, указанным в параграфе 22.1.1, для постоянной регистрации в этом реестре должно указываться поле Frame Type Name с кратким мнемоническим обозначением типа кадра.

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

22.5. Реестр кодов транспортных ошибок QUIC

Агентство IANA создало реестр QUIC Transport Error Codes в разделе QUIC. Реестр QUIC Transport Error Codes управляет 62-битовым пространством значений, разделенным на 3 части. Постоянные регистрации выполняются по процедуре Specification Required (параграф 4.6 в [RFC8126]), за исключением диапазона 0x00 – 0x3f (включительно), где применяется процедура Standards Action или IESG Approval в соответствии с параграфом 4.9 или 4.10 в [RFC8126].

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

Code

Краткое мнемоническое обозначение параметра.

Description

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

Исходное содержимое реестра приведено в таблице 7.

Таблица 7. Исходные записи реестра транспортных ошибок QUIC.

Значение

Код

Описание

Документ

0x00

NO_ERROR

Нет ошибок

Раздел 20

0x01

INTERNAL_ERROR

Ошибка реализации

Раздел 20

0x02

CONNECTION_REFUSED

Сервер отклонил соединение

Раздел 20

0x03

FLOW_CONTROL_ERROR

Ошибка управления потоком данных

Раздел 20

0x04

STREAM_LIMIT_ERROR

Открыто слишком много потоков

Раздел 20

0x05

STREAM_STATE_ERROR

Кадр получен в недействительном состоянии потока

Раздел 20

0x06

FINAL_SIZE_ERROR

Изменение окончательного размера

Раздел 20

0x07

FRAME_ENCODING_ERROR

Ошибка кодирования кадра

Раздел 20

0x08

TRANSPORT_PARAMETER_ERROR

Ошибка в транспортных параметрах

Раздел 20

0x09

CONNECTION_ID_LIMIT_ERROR

Получено слишком много идентификаторов соединения

Раздел 20

0x0a

PROTOCOL_VIOLATION

Нарушение базового протокола

Раздел 20

0x0b

INVALID_TOKEN

Получен недействительный маркер

Раздел 20

0x0c

APPLICATION_ERROR

Ошибка приложения

Раздел 20

0x0d

CRYPTO_BUFFER_EXCEEDED

Переполнение буфера данных CRYPTO

Раздел 20

0x0e

KEY_UPDATE_ERROR

Недействительное обновление защиты пакета

Раздел 20

0x0f

AEAD_LIMIT_REACHED

Избыточное применение ключей защиты пакетов

Раздел 20

0x10

NO_VIABLE_PATH

Нет подходящего пути через сеть

Раздел 20

0x0100-0x01ff

CRYPTO_ERROR

Код сигнала TLS

Раздел 20

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

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

[BCP38] Ferguson, P. and D. Senie, “Network Ingress Filtering: Defeating Denial of Service Attacks which employ IP Source Address Spoofing”, BCP 38, RFC 2827, May 2000. <https://www.rfc-editor.org/info/bcp38>

[DPLPMTUD] Fairhurst, G., Jones, T., Tüxen, M., Rüngeler, I., and T. Völker, “Packetization Layer Path MTU Discovery for Datagram Transports”, RFC 8899, DOI 10.17487/RFC8899, September 2020, <https://www.rfc-editor.org/info/rfc8899>.

[EARLY-ASSIGN] Cotton, M., “Early IANA Allocation of Standards Track Code Points”, BCP 100, RFC 7120, DOI 10.17487/RFC7120, January 2014, <https://www.rfc-editor.org/info/rfc7120>.

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

[QUIC-INVARIANTS] Thomson, M., “Version-Independent Properties of QUIC”, RFC 8999, DOI 10.17487/RFC8999, May 2021, <https://www.rfc-editor.org/info/rfc8999>.

[QUIC-RECOVERY] Iyengar, J., Ed. and I. Swett, Ed., “QUIC Loss Detection and Congestion Control”, RFC 9002, DOI 10.17487/RFC9002, May 2021, <https://www.rfc-editor.org/info/rfc9002>.

[QUIC-TLS] Thomson, M., Ed. and S. Turner, Ed., “Using TLS to Secure QUIC”, RFC 9001, DOI 10.17487/RFC9001, May 2021, <https://www.rfc-editor.org/info/rfc9001>.

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

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

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

[RFC3629] Yergeau, F., “UTF-8, a transformation format of ISO 10646”, STD 63, RFC 3629, DOI 10.17487/RFC3629, November 2003, <https://www.rfc-editor.org/info/rfc3629>.

[RFC6437] Amante, S., Carpenter, B., Jiang, S., and J. Rajahalme, “IPv6 Flow Label Specification”, RFC 6437, DOI 10.17487/RFC6437, November 2011, <https://www.rfc-editor.org/info/rfc6437>.

[RFC8085] Eggert, L., Fairhurst, G., and G. Shepherd, “UDP Usage Guidelines”, BCP 145, RFC 8085, DOI 10.17487/RFC8085, March 2017, <https://www.rfc-editor.org/info/rfc8085>.

[RFC8126] Cotton, M., Leiba, B., and T. Narten, “Guidelines for Writing an IANA Considerations Section in RFCs”, BCP 26, RFC 8126, DOI 10.17487/RFC8126, June 2017, <https://www.rfc-editor.org/info/rfc8126>.

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

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

[RFC8311] Black, D., “Relaxing Restrictions on Explicit Congestion Notification (ECN) Experimentation”, RFC 8311, DOI 10.17487/RFC8311, January 2018, <https://www.rfc-editor.org/info/rfc8311>.

[TLS13] Rescorla, E., “The Transport Layer Security (TLS) Protocol Version 1.3”, RFC 8446, DOI 10.17487/RFC8446, August 2018, <https://www.rfc-editor.org/info/rfc8446>.

[UDP] Postel, J., “User Datagram Protocol”, STD 6, RFC 768, DOI 10.17487/RFC0768, August 1980, <https://www.rfc-editor.org/info/rfc768>.

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

[AEAD] McGrew, D., “An Interface and Algorithms for Authenticated Encryption”, RFC 5116, DOI 10.17487/RFC5116, January 2008, <https://www.rfc-editor.org/info/rfc5116>.

[ALPN] Friedl, S., Popov, A., Langley, A., and E. Stephan, “Transport Layer Security (TLS) Application-Layer Protocol Negotiation Extension”, RFC 7301, DOI 10.17487/RFC7301, July 2014, <https://www.rfc-editor.org/info/rfc7301>.

[ALTSVC] Nottingham, M., McManus, P., and J. Reschke, “HTTP Alternative Services”, RFC 7838, DOI 10.17487/RFC7838, April 2016, <https://www.rfc-editor.org/info/rfc7838>.

[COOKIE] Barth, A., “HTTP State Management Mechanism”, RFC 6265, DOI 10.17487/RFC6265, April 2011, <https://www.rfc-editor.org/info/rfc6265>.

[CSRF] Barth, A., Jackson, C., and J. Mitchell, “Robust defenses for cross-site request forgery”, Proceedings of the 15th ACM conference on Computer and communications security – CCS ’08, DOI 10.1145/1455770.1455782, 2008, <https://doi.org/10.1145/1455770.1455782>.

[EARLY-DESIGN] Roskind, J., “QUIC: Multiplexed Stream Transport Over UDP”, 2 December 2013, <https://docs.google.com/document/d/1RNHkx_VvKWyWg6Lr8SZ-saqsQx7rFV-ev2jRFUoVD34/edit?usp=sharing>.

[GATEWAY] Hätönen, S., Nyrhinen, A., Eggert, L., Strowes, S., Sarolahti, P., and M. Kojo, “An experimental study of home gateway characteristics”, Proceedings of the 10th ACM SIGCOMM conference on Internet measurement – IMC ’10, DOI 10.1145/1879141.1879174, November 2010, <https://doi.org/10.1145/1879141.1879174>.

[HTTP2] Belshe, M., Peon, R., and M. Thomson, Ed., “Hypertext Transfer Protocol Version 2 (HTTP/2)”, RFC 7540, DOI 10.17487/RFC7540, May 2015, <https://www.rfc-editor.org/info/rfc7540>.

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

[QUIC-MANAGEABILITY] Kuehlewind, M. and B. Trammell, “Manageability of the QUIC Transport Protocol”, Work in Progress, Internet-Draft, draft-ietf-quic-manageability-11, 21 April 2021, <https://tools.ietf.org/html/draft-ietf-quic-manageability-11>.

[RANDOM] Eastlake 3rd, D., Schiller, J., and S. Crocker, “Randomness Requirements for Security”, BCP 106, RFC 4086, DOI 10.17487/RFC4086, June 2005, <https://www.rfc-editor.org/info/rfc4086>.

[RFC1812] Baker, F., Ed., “Requirements for IP Version 4 Routers”, RFC 1812, DOI 10.17487/RFC1812, June 1995, <https://www.rfc-editor.org/info/rfc1812>.

[RFC1918] Rekhter, Y., Moskowitz, B., Karrenberg, D., de Groot, G. J., and E. Lear, “Address Allocation for Private Internets”, BCP 5, RFC 1918, DOI 10.17487/RFC1918, February 1996, <https://www.rfc-editor.org/info/rfc1918>.

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

[RFC2104] Krawczyk, H., Bellare, M., and R. Canetti, “HMAC: Keyed-Hashing for Message Authentication”, RFC 2104, DOI 10.17487/RFC2104, February 1997, <https://www.rfc-editor.org/info/rfc2104>.

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

[RFC4193] Hinden, R. and B. Haberman, “Unique Local IPv6 Unicast Addresses”, RFC 4193, DOI 10.17487/RFC4193, October 2005, <https://www.rfc-editor.org/info/rfc4193>.

[RFC4291] Hinden, R. and S. Deering, “IP Version 6 Addressing Architecture”, RFC 4291, DOI 10.17487/RFC4291, February 2006, <https://www.rfc-editor.org/info/rfc4291>.

[RFC4443] Conta, A., Deering, S., and M. Gupta, Ed., “Internet Control Message Protocol (ICMPv6) for the Internet Protocol Version 6 (IPv6) Specification”, STD 89, RFC 4443, DOI 10.17487/RFC4443, March 2006, <https://www.rfc-editor.org/info/rfc4443>.

[RFC4787] Audet, F., Ed. and C. Jennings, “Network Address Translation (NAT) Behavioral Requirements for Unicast UDP”, BCP 127, RFC 4787, DOI 10.17487/RFC4787, January 2007, <https://www.rfc-editor.org/info/rfc4787>.

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

[RFC5869] Krawczyk, H. and P. Eronen, “HMAC-based Extract-and-Expand Key Derivation Function (HKDF)”, RFC 5869, DOI 10.17487/RFC5869, May 2010, <https://www.rfc-editor.org/info/rfc5869>.

[RFC7983] Petit-Huguenin, M. and G. Salgueiro, “Multiplexing Scheme Updates for Secure Real-time Transport Protocol (SRTP) Extension for Datagram Transport Layer Security (DTLS)”, RFC 7983, DOI 10.17487/RFC7983, September 2016, <https://www.rfc-editor.org/info/rfc7983>.

[RFC8087] Fairhurst, G. and M. Welzl, “The Benefits of Using Explicit Congestion Notification (ECN)”, RFC 8087, DOI 10.17487/RFC8087, March 2017, <https://www.rfc-editor.org/info/rfc8087>.

[RFC8981] Gont, F., Krishnan, S., Narten, T., and R. Draves, “Temporary Address Extensions for Stateless Address Autoconfiguration in IPv6”, RFC 8981, DOI 10.17487/RFC8981, February 2021, <https://www.rfc-editor.org/info/rfc8981>.

[SEC-CONS] Rescorla, E. and B. Korver, “Guidelines for Writing RFC Text on Security Considerations”, BCP 72, RFC 3552, DOI 10.17487/RFC3552, July 2003, <https://www.rfc-editor.org/info/rfc3552>.

[SLOWLORIS] “RSnake” Hansen, R., “Welcome to Slowloris – the low bandwidth, yet greedy and poisonous HTTP client!”, June 2009, <https://web.archive.org/web/20150315054838/http://ha.ckers.org/slowloris/>.

Приложение A. Псевдокод

В этом приложении описан псевдокод примеров алгоритмов с упором на корректность и ясность, а не производительность.

Сегменты псевдокода лицензируются как компоненты кода (Code Component, см. «Авторские права»).

A.1. Пример декодирования целого числа с переменным размером

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

   ReadVarint(data):
     // Размер целых чисел кодируется 2 первыми битами первого байта.
     v = data.next_byte()
     prefix = v >> 6
     length = 1 << prefix

     // Когда размер известен, эти биты удаляются и считываются
     // остальные байты.
     v = v & 0x3f
     повтор length-1 раз:
       v = (v << 8) + data.next_byte()
     return v

Рисунок 45. Пример декодирования целого числа с переменным размером.


Например, 8-байтовая последовательность 0xc2197c5eff14e88c декодируется в десятичное число 151288809941952652, 4-байтовая последовательность 0x9d7f3e7d – в 494878333, 2-байтовая последовательность 0x7bbd – в 15293, а однобайтовая последовательность 0x25 – в 37 (как и двухбайтовая 0x4025).

A.2. Пример алгоритма кодирования номеров пакетов

Псевдокод на рисунке 46 показывает, как реализация может выбрать подходящий размер для кодирования номера пакета. Функция EncodePacketNumber принимает 2 аргумента – full_pn задаёт полный номер пакета, который будет передан, largest_acked – наибольший номер пакета, подтверждённый партнёром в текущем пространстве номеров.

  EncodePacketNumber(full_pn, largest_acked):
     // Число битов должно быть по меньшей мере на 1 больше 
     // двоичного логарифма числа непрерывных неподтвержденных
     // номеров пакетов, включая новый пакет.
     if largest_acked is None:
       num_unacked = full_pn + 1
     else:
       num_unacked = full_pn - largest_acked

     min_bits = log(num_unacked, 2) + 1
     num_bytes = ceil(min_bits / 8)

     // Кодирование целого числа и отсечка до num_bytes
     // младших байтов.
     return encode(full_pn, num_bytes)

Рисунок 46. Простой алгоритм декодирования номера пакета.


Например, если конечная точка получила подтверждение для пакета 0xabe8b3 и передаёт пакет с номером 0xac5c02, имеется 29519 (0x734f) остающихся пакетов. Для представления по меньшей мере удвоенного диапазона (59038 пакетов или 0xe69e) требуется 16 битов. В том же состоянии при отправке пакета с номером 0xace8fe используется 24-битовое кодирование, поскольку требуется не менее 18 для представления удвоенного диапазона (131222 пакетов или 0x020096).

A.3. Пример алгоритма декодирования номеров пакетов

   DecodePacketNumber(largest_pn, truncated_pn, pn_nbits):
      expected_pn  = largest_pn + 1
      pn_win       = 1 << pn_nbits
      pn_hwin      = pn_win / 2
      pn_mask      = pn_win - 1
      // Входящему пакету следует быть больше expected_pn — pn_hwin,
      // но не больше expected_pn + pn_hwin. Это означает, что
      // нельзя просто вырезать биты после expected_pn и добавить
      // truncated_pn, поскольку значение может выйти из окна.
      //
      // Следующий код рассчитывает значение-кандидат и проверяет
      // его попадание в окно номеров. Дополнительная проверка
      // предотвращает переполнение и опустошение.
      candidate_pn = (expected_pn & ~pn_mask) | truncated_pn
      if candidate_pn <= expected_pn - pn_hwin and
         candidate_pn < (1 << 62) - pn_win:
         return candidate_pn + pn_win
      if candidate_pn > expected_pn + pn_hwin and
         candidate_pn >= pn_win:
         return candidate_pn - pn_win
      return candidate_pn

Рисунок 47. Пример алгоритма декодирования номера пакета.


Псевдокод на рисунке 47 показывает пример алгоритма декодирования номера пакета после снятия защиты заголовка. Функция DecodePacketNumber принимает 3 аргумента – largest_pn указывает наибольший номер успешно обработанного пакета из текущего пространства номеров, truncated_pn содержит значение поля Packet Number, pn_nbits указывает число битов в поле Packet Number (8, 16, 24 или 32). Например, если максимальный номер успешно аутентифицированного пакета составляет 0xa82f30ea, 16-битовое значение 0x9b32 будет декодировано как 0xa82f9b32.

A.4. Пример алгоритма проверки ECN

Каждый раз, когда конечная точка начинает передачу пакетов по новому пути, она проверяет поддержку ECN на этом пути (см. параграф 13.4). Если путь поддерживает ECN, ставится цель использовать ECN. Конечные точки могут также периодически снова проверять путь, который указал отсутствие поддержки ECN.

В этом параграфе описан один из методов проверки пути, но конечные точки могут применять и другие методы.

Пути назначается одно из состояний – testing (проверка), unknown (неизвестно), failed (отказ), capable (поддержка). На путях с состоянием testing или capable конечная точка по умолчанию передаёт пакеты с маркировкой ECT(0), в остальных случаях пакеты не маркируются. Для начала проверки пути устанавливается статус ECN testing и имеющиеся значения счётчиков ECN запоминаются как базовые.

Период тестирования ограничивается числом пакетов или временем, задаваемым конечной точкой. Цель состоит не в ограничении продолжительности тестирования, а в обеспечении передачи достаточного числа маркированных пакетов для получения значений счётчиков ECN, обеспечивающих чёткую индикацию трактовки маркированных пакетов на пути. В параграфе 13.4.2 предлагается устанавливать ограничение в 10 пакетов или 3 интервала PTO.

По завершении тестирования статус ECN для пути становится unknown. Из этого состояния успешная проверка счётчиков ECN в кадре ACK (см. параграф 13.4.2.1) меняет состояние ECN для пути на capable, если не был подтверждён ни один маркированный пакет. При отказе проверки счётчиков ECN статус ECN для пути становится failed. Конечная точка может установить этот статус также в случае обнаружения потери маркированных пакетов или установки для всех таких пакетов маркера ECN-CE.

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

Участники работы

Первоначальное устройство и обоснование этого протокола в значительной степени основаны на работе Jim Roskind [EARLY-DESIGN]. Рабочая группа IETF QUIC получила огромную поддержку от многих людей. Ниже перечислены люди, внёсшие существенный вклад в этот документ.

Alessandro Ghedini

Alyssa Wilk

Antoine Delignat-Lavaud

Brian Trammell

Christian Huitema

Colin Perkins

David Schinazi

Dmitri Tikhonov

Eric Kinnear

Eric Rescorla

Gorry Fairhurst

Ian Swett

Igor Lubashev

奥 一穂 (Kazuho Oku)

Lars Eggert

Lucas Pardue

Magnus Westerlund

Marten Seemann

Martin Duke

Mike Bishop

Mikkel Fahnøe Jørgensen

Mirja Kühlewind

Nick Banks

Nick Harper

Patrick McManus

Roberto Peon

Ryan Hamilton

Subodh Iyengar

Tatsuhiro Tsujikawa

Ted Hardie

Tom Jones

Victor Vasiliev

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

Jana Iyengar (editor)

Fastly

Email: jri.ietf@gmail.com

Martin Thomson (editor)

Mozilla

Email: mt@lowentropy.net

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

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

nmalykh@protokols.ru

1Congestion Experienced – наличие перегрузки.

2ECN-Capable Transport – транспорт с поддержкой ECN.

3Path Maximum Transmission Unit Discovery – определение MTU на пути.

4Datagram Packetization Layer PMTU Discovery – определение MTU на пути для пакетизации дейтаграмм.

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

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