RFC: 793
Оригинал: Transmission Control Protocol
Предыдущие версии: RFC 761
Категория: Стандарт Интернета
Дата публикации:
Автор:
Перевод: Николай Малых

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

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

Важно помнить, что реальное пространство порядковых номеров имеет ограниченные размеры, хотя и достаточно велико (от 0 до 2^32 - 1). Поскольку число порядковых номеров конечно, все арифметические операции с порядковыми номерами выполняются по модулю 2^32. Такая беззнаковая арифметика сохраняет соотношения между порядковыми номерами при переходе номера от 2^32 - 1 к нулю. В такой арифметике с использованием модуля существуют некоторые тонкости, которые следует принимать во внимание при разработке программ, использующих сравнение значений. Символ =< означает "меньше или равно" (модуль 2^32).

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

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

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

  • SND.UNA = самый старый неподтвержденный номер
  • SND.NXT = порядковый номер для следующей передачи
  • SEG.ACK = подтверждение от принимающего TCP (следующий порядковый номер, ожидаемый TCP)
  • SEG.SEQ = первый порядковый номер для сегмента
  • SEG.LEN = число октетов в сегменте, занятых данными (с учетом SYN и FIN)
  • SEG.SEQ+SEG.LEN-1 = последний порядковый номер для сегмента

Для новых подтверждений (их называют acceptable ack — подтверждение доступности) должно выполняться неравенство:

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

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

Для приема данных должны выполняться проверки следующих параметров:

  • RCV.NXT = следующий порядковый номер, ожидаемый во входящем сегменте и находящийся в левой (или нижней) части окна приема
  • RCV.NXT+RCV.WND-1 = последний порядковый номер, ожидаемый во входящем сегменте и находящийся в правой (или верхней) части окна приема
  • SEG.SEQ = первый порядковый номер, занимаемый входящим сегментом
  • SEG.SEQ+SEG.LEN-1 = последний порядковый номер, занимаемый входящим сегментом

Сегмент считается занимающим часть корректного пространства порядковых номеров при условии:

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

или

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

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

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

Размер сегментаПриемное окноПроверка
00SEG.SEQ = RCV.NXT
0>0RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND
>00неприемлемо
>0>0RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND или
RCV.NXT =< SEG.SEQ+SEG.LEN-1 < RCV.NXT+RCV.WND

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

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

2007 - 2017 © Русские переводы RFC, IETF, ISOC.