RFC: 4340
Оригинал: Datagram Congestion Control Protocol (DCCP)
Категория: Предложенный стандарт
Дата публикации:
Авторы: , ,
Перевод: Николай Малых

8.5. Псевдокод

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

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

  • S.SWL — нижний предел окна порядковых номеров;
  • S.SWH — верхний предел окна порядковых номеров;
  • S.AWL — нижний предел окна номеров подтверждений;
  • S.AWH — верхний предел окна номеров подтверждений;
  • S.ISS — начальный порядковый номер в переданном пакете;
  • S.ISR — начальный порядковый номер в принятом пакете;
  • S.OSR — порядковый номер в первом пакете, принятом в состоянии OPEN;
  • S.GSS — максимальный порядковый номер в переданных пакетах;
  • S.GSR — максимальный порядковый номер в принятых пакетах;
  • S.GAR — максимальный корректный номер подтверждения, принятый в пакетах, отличных от Sync; инициализируется значение S.ISS

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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