On-Line Библиотека www.XServer.ru - учебники, книги, статьи, документация, нормативная литература.
       Главная         В избранное         Контакты        Карта сайта   
    Навигация XServer.ru








 

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

   Обработка, описанная в данной главе, является лишь примером 
одной из возможных реализаций протокола. Иные реализации могут 
иметь несколько иные процедуры обработки, однако они должны отли- 
чаться от описанных в данной главе лишь в деталях, но никак не по 
существу.
   Деятельность программы протокола TCP можно рассматривать как 
реагирование на события. Эти происходящие события можно разбивать 
на три категории: запросы клиентов, прибытие сегментов, истечение 
контрольного времени. Данная глава описывает деятельность в прото- 
коле TCP в ответ на каждое их этих событий. Во многих случаях не- 
обходимая обработка зависит от состояния соединения. События, ко- 
торые могут произойти:
   Команды клиента
   - на открытие соединения
   - на посылку данных
   - на получение данных
   - на закрытие соединения
   - на ликвидацию соединения
   - на определение статуса соединения
   Получения сегментов
   Истечение контрольного времени
   - для действий клиента
   - для повторной посылки
   - в состоянии ожидания
   Модель интерфейса TCP и клиента состоит в том, что команды кли- 
ента выполняются немедленно, а вероятный отложенный отчет предо- 
ставляется через механизм событий или псевдопрерываний. В дальней- 
шем описании понятие "сигнал" может обозначать некое основание для 
посылки отложенного отчета.
   Сообщение об ошибках пердоставляется в виде текстовых строк. 
Например, команды клиента, адресованные к несуществующим соедине- 
ниям, получат сообщение "error: connection not open".
   Пожалуйста учтите, что в дальнейшем вся арифметика для номеров 
очереди, номеров подтверждения, окон и т.д. осуществляется по мо- 
дулю 2**32, что соответствует размеру множества номеров очередей. 
Заметим также, что "=<" означает "меньше или равно" (по модулю 
2**32). 
   Чтобы постичь смысл обработки приходящих сегментов, естествен- 
ным было бы представить, что они сперва проверяются на коррект- 
ность номера очереди (т.е. что их информация попадает в диапазон 
"окна получения" среди ожидаемых номеров очереди) и что они, в 
общем случае, будут ставиться в очередь и подвергаться обработке 
соответственно своим номерам.
   Если одни сегменты перекрываются с другими, ранее полученными 
сегментами, то мы конструируем сегмент, содержащий лишь действи- 
тельно новые данные, а затем соответствующим образом корректируем 
поля заголовка.
   Заметим, что состояние программы протокола TCP остается при 
обработке событий без изменений, если обратное не указано особо.

Запрос OPEN
   Состояние CLOSED (т.е. блок TCB отсутствует)
         Создать новый блок управления передачей (TCB) для хране- 
      ния информации о состоянии соединения. Заполнить поля иден- 
      тификатора местного сокета, чужого сокета, приоритета, за- 
      крытости/безопасности, а также контрольного времени для кли- 
      ента. Заметим, что некоторые параметры чужого сокета могут 
      остаться неконкретизированными при пассивном открытии и со- 
      ответствующие им поля должны быть заданы исходя из парамет- 
      ров пришедшего SYN сигнала. Клиенту может быть предоставлена 
      возможность проверять параметры безопасности и приоритета, 
      если в ответ на такой запрос не будет получено сообщение 
      "error: precedence not allowed" или "error: security/ 
      compartment not allowed". В случае пассивного открытия 
      следует перейти в состояние LISTEN и вернуть управление дав- 
      шему команду OPEN процессу. Если открытие является активным, 
      а чужой сокет не конкретизирован, то вернуть сообщение 
      "error: fireign socket unspecified". Если открытие является 
      активным и указан чужой сокет, то послать сегмент с сигналом 
      SYN. Выбирается начальный номер для очереди отправления. 
      Посылаемый сегмент и сигналом SYN имеет форму 
      <SEQ=ISS><CTL=SYN>. Установить переменную SND.UNA в ISS, а 
      SND.NXT - в ISS+1. Перейти в состояние SYN-SENT. Вернуть 
      управление процессу, вызвавшему рассматриваемую команду.
         Если сделавший запрос клиент не получил доступа к указан- 
      ному в запросе сокету, то вернуть сообщение "error: 
      connection illegal for this process". Если для создания но- 
      вого соединения нет места в памяти компьютера, то вернуть 
      сообщение "error: insufficient resources".
   Состояние LISTEN
         Если происходит активизация и указан чужой сокет, то сме- 
      нить состояние соединения с пассивного на активный, выбрать 
      ISS. Послать сегмент с сигналом SYN, занести в SND.UNA зна- 
      чение ISS, а в SND.NXT - ISS+1. Перейти в SYN-SEND состо- 
      яние. Данные, указанные в команде SEND, могут быть посланы в 
      том же сегменте с сигналом SYN, или же могут быть помещены в 
      очередь на передачу, которая может быть осуществлена после 
      перехода в ESTABLISHED состояние. Если в команде сделан за- 
      прос на применение бита срочности, то в результате ее выпол- 
      нения должны быть посланы сегменты данных. Если в очереди 
      заказов на пересылку нет места, то в результате будет полу- 
      чен ответ "error: insufficient resources". Если чужой сокет 
      не указан, то вернуть сообщение "error: foreign socket 
      unspecified"
   Состояния
      SYN-SENT
      SYN-RECEIVED
      ESTABLISHED
      FIN-WAIT-1
      FIN-WAIT-2
      CLOSE-WAIT
      CLOSING
      LAST-ACK
      TIME-WAIT
      возвращают в ответ на команду открытия сообщение "error: 
      connection already exist"

Запрос SEND
   Состояние CLOSED (например, нет блока TCB)
         Если клиент не имеет доступа к такому соединению, то вер- 
      нуть сообщение "error: connection illegal for this process". 
      В противном случае вернуть "error: connection does not 
      exist".
   Состояние LISTEN
         Если указан чужой сокет, то сменить состояние соединения 
      с пассивного на активный, выбрать номер ISS. Послать сегмент 
      с сигналом SYN, установить SND.UNA в ISS, а SND.NXT - в 
      ISS+1. Установить новое состояние SYN-SENT. Данные из вызова 
      SEND могут быть посланы вместе с сигналом SYN, а могут быть 
      помещены в очередь и отправлены уже после установления 
      ESTABLISHED состояния. Если в команде дан запрос на примене- 
      ние бита срочности, то он должен быть передан вместе с сег- 
      ментом данных, возникающим при выполнении этой команды. Если 
      в очереди нет места для запроса, то вернуть сообщение 
      "error: insufficient resources". Если чужой сокет не указан, 
      то вернуть "error: foreign socket unspecified".
  Состояние SYN-SENT
  Состояние SYN-RECEIVED
         Поместить данные в очередь с тем, чтобы отправить после 
      установления ESTABLISHED состояния. Если в очереди нет мес- 
      та, то вернуть сообщение "error: insufficient resources".
   Состояние ESTABLISHED
   Состояние CLOSE-WAIT
         Сегментировать буфер данных и переслать его с ответным 
      подтверждением (значение подтверждения = RCV.NXT). Если для 
      размещения этого буфера недостаточно места в памяти, то 
      просто вернуть сообщение "error: insufficient resources".
         Если установлен флаг срочности, то занести в SND.UP зна- 
      чение SND.NXT-1 и установить указатель срочности на уходящие 
      сегменты.
   Состояния
      FIN-WAIT-1
      FIN-WAIT-2
      CLOSING
      LAST-ACK
      TIME-WAIT
         Вернуть сообщение "error: connection closing" и не выпол- 
      нять запрос клиента.

Запрос RECEIVE
   Состояние CLOSED (например, отсутствует блок TCB)
         Если клиент не имеет доступа к такому соединению, вернуть 
      сообщение "error: connection illegal for this process". В 
      противном случае вернуть сообщение "error: connection does 
      not exist".
   Состояния
      LISTEN
      SYN-SENT
      SYN-RECEIVED
         Поместить запрос в очередь на обслуживание после установ- 
      ления ESTABISHED состояния. Если в очереди для этого нет 
      места, вернуть сообщение "error: insufficient resources".
   Состояния
      ESTABLISHED
      FIN-WAIT-1
      FIN-WAIT-2
         Если в пришедших сегментах недостаточно данных для выпол- 
      нения данного запроса, поместить последний в очередь на об- 
      служивание. Если же в очереди нет места для размещения за- 
      проса RECEIVE, вернуть сообщение "error: insufficient 
      resources".
         Собрать данные из приходящих сегментов в буфере получе- 
      ния, а затем передать их клиенту. Установить флаг 
      "обнаружено проталкивание" (PUSH), если это имеет место.
         Если данным, передаваемым в настоящий момент клиенту, 
      предшествовал RCV.UP, то оповестить клиента о присутствии 
      срочных данных. Когда протокол TCP берет на себя ответствен- 
      ность за получение клиентом данных, то это фактически озна- 
      чает обмен информацией с отправителем в виде подтверждений. 
      Формирование такого подтверждения обсуждается ниже при рас- 
      смотрении алгоритма обработки приходящего сегмента.
   Состояние CLOSE-WAIT
         Поскольку партнер на другом конце соединения уже послал 
      сигнал FIN, то команды RECEIVE должны получать данные, уже 
      имеющиеся в системе, а не только те, которые уже переданы 
      клиенту. Если в системе больше нет текста, ждущего своего 
      запроса RECIVE, то передать клиенту сообщение "error 
      connection closing". В противном случае использовать для 
      удовлетворения запроса RECEIVE любую имеющуюся информацию.
   Состояния
      CLOSING
      LAST-ACK
      TIME-WAIT
         Вернуть сообщение "error connection closing".

Запрос CLOSE
   Состояние CLOSED (например, нет блока TCB)
         Если клиент не имеет доступа к такому соединению, вернуть 
      сообщение "error: connection illegal for this process". В 
      противном случае вернуть сообщение "error: connection does 
      not exist".
   Состояние LISTEN
         Любые остающиеся неудовлетворенными запросы RECEIVE будут 
      завершены с сообщением "error: closing". Стереть блок TCB, 
      перейти в CLOSED состояние и вернуть управление клиенту.
   Состояние SYN-SENT
         Стереть блок TCB и вернуть сообщение "error closing" для 
      любых еще остающихся в очередях запросов SEND или RECEIVE.
   Состояние SYN-RECEIVED
         Если не сделано каких-либо запросов SEND и нет данных, 
      ожидающих отправки, то сформировать FIN сегмент и послать 
      его, а затем перейти в FIN-WAIT-1 состояние. В противном 
      случае поместить данные в очередь для рассмотрения после 
      установления ESTABLISHED состояния.
   Состояние ESTABLISHED
         Поместить запрос в очередь в ожидании, когда все данные 
      предшествующих команд будут сегментированы. Тогда сформиро- 
      вать FIN сегмент и отправить его партнеру. В любом случае 
      перейти в FIN-WAIT-1 состояние.
   Состояние FIN-WAIT-1
   Cостояние FIN-WAIT-2
         Строго говоря, такая ситуация является ошибочной и должна 
      привести к получению клиентом сообщения "error: connection 
      closing". Однако может быть приемлемым также ответ "Ok", 
      пока не отправлен второй FIN (хотя первый FIN может быть 
      отправлен повторно).
   Состояние CLOSE-WAIT
         Поместить этот запрос в очередь, пока все предшествующие 
      запросы SEND не будут помещены в сегменты. Затем послать 
      сегмент с сигналом FIN, перейти в CLOSING состояние.
   Состояния
      CLOSING
      LAST-ACK
      TIME-WAIT
         Возвратить сообщение "error: connection closing".

Запрос ABORT
   Состояние CLOSED (например, нет блока TCB)
         Если клиент не имеет доступа к такому соединению, вернуть 
      сообщение "error: connection illegal for this process". В 
      противном случае вернуть сообщение "error: connection does 
      not exist".
   Состояние LISTEN
         Любые остающиеся запросы RECEIVED должны завершиться с 
      возвратом сообщения "error: connection reset". Стереть блок 
      TCB, перейти в состояние CLOSED, вернуть управление програм- 
      ме клиента.
   Состояние SYN-SENT
         Все находящиеся в очереди запросы SEND и RECEIVE должны 
      получить сообщение "connection reset", стереть блок TCB, 
      перейти в состояние CLOSED, вернуть управление клиенту.
   Состояния
      SYN-RECEIVED
      ESTABLISHED
      FIN-WAIT-1
      FIN-WAIT-2
      CLOSE-WAIT
         Послать сегмент перезагрузки
      <SEQ=SND.NXT><CTL=RST>
      Все находящиеся в очереди запросы SEND и RECEIVED должны 
      получить сообщение "connection reset". Все сегменты, находя- 
      щиеся в очереди на передачу (за исключением только что сфор- 
      мированного сигнала RST) и в очереди на повторную пересылку 
      должны быть ликвидированы. Стереть блок TCB, перейти в 
      CLOSED состояние, вернуть управление клиенту.
   Состояния
      CLOSING
      LAST-ACK
      TIME-WAIT
         Вернуть сообщение "ok" и стереть блок TCB, перейти в со- 
      стояние CLOSED, вернуть управление клиенту.

Запрос STATUS
   Состояние CLOSED (например, нет блока TCB)
         Если клиент не имеет доступа у такому соединению, то воз- 
      вратить сообщение "error: connection illegal for this 
      process". В противном случае вернуть "error: connection does 
      not exist".
   Состояние LISTEN
      Вернуть сообщение "state=LISTEN" и указатель на блок TCB.
   Состояние SYN-SENT
      Вернуть сообщение "state=SYN-SENT" и указатель на блок TCB.
   Состояние SYN-RECEIVED
      Вернуть сообщение "state=SYNRECEIVED" и указатель на болк 
      TCB.
   Состояние ESTABLISHED
      Вернуть сообщение "state=ESTABLISHED" и указатель на блок 
      TCB.
   Состояние FIN-WAIT-1
      Вернуть сообщение "state=FIN-WAIT-1" и указатель на блок 
      TCB.
   Состояние FIN-WAIT-2
      Вернуть сообщение "state=FIN-WAIT-2" и указатель на блок 
      TCB.
   Состояние CLOSE-WAIT
      Вернуть сообщение "state=CLOSE-WAIT" и указатель на блок 
      TCB.
   Состояние CLOSING
      Вернуть сообщение "state=CLOSING" и указатель на блок TCB.
   Состояние LAST-ACK
      Вернуть сообщение "state=LAST-ACK" и указатель на блок TCB.
   Состояние TIME-WAIT
      Вернуть сообщение "state=TIME-WAIT" и указатель на блок TCB.

Приход сегментов
   Если состояние соединения CLOSED (например, нет блока TCB), то 
      все данные из указанного сегмента будут выброшены. Сегмент, 
      пришедший с сигналом RST, будет ликвидирован. Сегмент же, не 
      содержащий сигнала RST, вызовет посылку сигнала RST в ответ. 
      Подтверждение и номер очереди будут выбраны таким образом, 
      чтобы сделать последовательность перезагрузки приемлемой для 
      программы TCP, отправившей сегмент, который и вызвал такую 
      реакцию.
         Если бит ACK сброшен, то используется номер очереди нуль:
      <SEQ=0><ACK=SEG.SEQ+SEG.LEN><CTL=RST,ACK>
      Если же ACK установлен, то
      <SEQ=SEG.ACK><CTL=RST>
      Вернуть управление прерванной программе.
   Если состояние соединения LISTEN, то
         Сперва проверить присутствие сигнала RST. 
      Сигнал RST, пришедший вместе с сегментом, должен игнориро- 
      ваться, а управление должно быть возвращено прерванной про- 
      грамме.
         Во-вторых, проверить на присутствие ACK.
      Любое подтверждение является ошибкой, если оно пришло на 
      конец соединения, все еще находящийся в состоянии LISTEN. В 
      ответ на любой сегмент, пришедший с ACK, должен быть сформи- 
      рован приемлемый сегмент с сигналом перезагрузки. Сигнал RST 
      должен быть сформирован следующим образом:
      <SEQ=SEG.ACK><CTL=RST>
      Вернуть управление прерванной программе.
         В-третьих, проверить на присутствие сигнала SYN
      Если установлен бит SYN, то проверить безопасность. Если 
      значение параметра безопасность/закрытость в пришедшем сег- 
      менте не совпадает в точности со значением безопасность/ 
      закрытость в блоке TCB, то послать сигнал перезагрузки и 
      вернуть управление прерванной программе:
      <SEQ=SEG.ACK><CTL=RST>
      Если значение SEQ.PRC меньше, чем TCB.PRC, то перейти к сле- 
      дующему пункту. Установить RCV.NXT в SEG.SEQ+1, IRS устано- 
      вить в SEG.SEQ, а остальные тексты и функции управления по- 
      местить в очередь для последующей обработки. Выбрать значе- 
      ние для ISS и отправить сегмент подтверждения в форме
      <SEQ=ISS><ACK=RCV.NXT><CTL=SYN,ACK>
      Переменную SND.NXT установить в ISS+1, а SND.UNA - в ISS. 
      Установить для соединения новое состояние - SYN-RECEIVED. 
      Заметим, что в состоянии SYN-RECEIVED будут обрабатываться 
      все приходящие данные и команды управления (вместе с SYN), 
      но уже не будет как прежде осуществляться обработка сигналов 
      SYN и ACK. Если состояние LISTEN не сформулировано полностью 
      (например, не указан исчерпывающе чужой сокет, то именно в 
      этот момент должны быть доопределены поля блока TCB, остав- 
      шиеся незаполненными.
         В-четвертых, искать в пришедшем сегменте остальные коман- 
      ды управления, а также собственно данные. Любые сегменты с 
      иными командами управления или заполненные текстом (но не 
      содержащие сигнала SYN) должны получить от местной программы 
      TCP подтверждение, и, таким образом, будут отброшены во вре- 
      мя работы с подтверждением. Приходящий сегмент с сигналом 
      RST не может быть правильным, поскольку он не может являться 
      ответом на информацию, переданную данной реализацией соеди- 
      нения. Так что Вы вряд ли получите это сигнал, но если это 
      произойдет, выбросьте пришедший сегмент и верните управление 
      прерванной программе.

   Если состояние соединения SYN-SENT
         Во-первых, проверить бит ACK Если бит ACK выставлен, то 
         В случае, если SEG.ACK = <ISS или SEG.ACK > SND.NXT,
            послать сигнал перезагрузки
            <SEQ=SEG.ACK><CTL=RST>
            (Если не выставлен бит RST. Если он все же выставлен, 
            то, ничего не делая выкинуть пришедший сегмент и вер- 
            нуть управление прерванной программе.) Ликвидировать 
            сегмент, вернуть управление.
         Если SND.UNA =< SEG.ACK =< SND.NXT, то полученное в сег- 
            менте подтверждение становится приемлемым.
         Во-вторых, проверить бит RST.
            В случае,если бит RST выставлен
               Если ожидалось получение сегмента с подтверждением, 
               то дать клиету объявление "error: connection 
               reset", вернуть сегмент, перейти в состояние 
               CLOSED, убрать блок TCB, и, наконец, вернуть управ- 
               ление прерванной программе. В противном случае (нет 
               подтверждения) ликвидировать сегмент и вернуть 
               управление.
         В-третьих, проверить уровни безопасности и приоритета
            Если в пришедшем сегменте значения полей безопасность/ 
               закрытость не совпадают в точности со значениями в 
               блоке TCB, то послать сигнал перезагрузки, а точнее
               если имеется ACK, то послать 
               <SEQ=SEG.ACK><CTL=RST>
               в противном случае послать
               <SEQ=0><ACK=SEG.SEQ+SEG.LEN><CTL=RST,ACK>
            Если имеется значение ACK, то
               приоритет в пришедшем сегменте должен совпадать с 
               приоритетом, указанным в блоке TCB. Если это не 
               так, то послать сигнал перезагрузки
               <SEQ=SEG.ACK><CTL=RST>
            Если же ACK отсутствует, то выполнить следующее
               Если в сегмете указан приоритет выше, чем приоритет 
               в блоке TCB, то, если это позволяют клиент и систе- 
               ма, увеличить значение приоритета в блоке TCB до 
               значения, указанного в сегменте. Если же увеличи- 
               вать приоритет не разрешается, послать сигнал пере- 
               загрузки:
               <SEQ=0><ACK=SEG.SEQ+SEG.LEN><CTL=RST,ACK>
               Если в сегменте указан приоритет, меньший, чем в 
               блоке TCB, то просто перейти к следующему пункту 
               анализа.
         В-четвертых, проверить установку бита SYN. Данный этап 
     должен осуществляться только если бит ACK не вызывает про- 
     блем, или если он не установлен, сегмент также не содержит 
     сигнала RST. 
     Если бит SYN установлен и параметры безопасности/ закрытости 
     приоритета являются приемлемыми, то в переменную SEG.NXT за- 
     писать значение SEG.SEQ+1, а IRS установить равным SEG.SEQ. 
     SND.UNA должно быть повышено до SEG.ACK (если имеется ACK), а 
     любые сегметы в очереди на повторную посылку, получившие та- 
     ким образом подтверждение, должны быть удалены.
     Если SND.UNA > ISS (наш сигнал SYN получит подтверждение), то 
     установить для соединения состояние ECTABLISHED и сформиро- 
     вать ACK сегмент
     <SEQ-SND.NXT><ACK=RCV.NXT><CTL=ACK>
     и отправить его. В этот сегмент могут быть включены данные 
     или команды из очереди на отправление. Если в пришедшем сег- 
     менте есть иные команды или даже некий текст в поле данных, 
     то продолжить обработку далее, начиная с шестого этапа ниже, 
     где осуществляется проверка бита URG. Если таких команд и 
     данных нет, передать управление прерванной программе.
     Если же бит SYN не установлен, то перейти в состояние 
     SYN-RECEIVED, сформировать сегмент SYN, ACK:
     <SEQ=ISS><ACK=RCV.NXT><CTL=SYN,ACK>
     и послать его. Если в пришедшем сегменте имеются команды или 
     текст в поле данных, то поместить их в очередь для обработки 
     после установления ESTABLISH состояния. Вернуть управление 
     прерванной программе. 
        В-пятых, если установлены биты SYN или RST, то выкинуть 
     пришедший сегмент и вернуть управление прерванной программе.
Если во время прихода сегмента соединение находилось в состоянии, 
не описанном выше, то
   Во-первых, проверить номер очереди
      Состояния
      SYN-RECEIVED
         ESTABLISHED
         FIN-WAIT-1
         FIN-WAIT-2
         CLOSE-WAIT
         CLOSING
         LAST-ACK
         TIME-WAIT
         Сегменты обрабатываются по очереди. По получении сегмента 
     сперва осуществляется тест для удаления старых дубликатов, но 
     дальнейшая обработка осуществляется в порядке номеров 
     SEG.SEQ. Если содержимое сегмента перекрывает границу между 
     старой и пока новой информацией, то должны обрабатываться 
     только новые данные.
      Тест на приемлемость приходящего сегмента рассматривает че- 
      тыре варианта:
      Длина    Окно         Текст
      сегмента получения
         0       0       SEG.SEQ = RCV.NXT
         0      >0       RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND
        >0       0       сегмент неприемлем
        >0      >0       RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND
               или RCV.NXT =< SEG.SEQ+SEG.LEN-1 < RCV.NXT+RCV.WND
      Если RCV.WND нулевой, никакие сегменты не будут приемлимы, 
      однако должна быть специально оговорена приемлемость получе- 
      ния правильных сигналов ACK, URG и RST.
         Если приходящий сегмент неприемлем, то в ответ послать 
      его подтверждение
      <SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK>
      если бит RST не установлен (если он все же выставлен, то 
      выкинуть пришедший сегмент и вернуть управление прерванной 
      программе. )
      После посылки подтверждения ликвидировать непринятый сегмент 
      и вернуть управление прерванной программе.
         В дальнейшем рекомендации строятся на предположении, что 
      пришедший сегмент является идеализированным и начинается с 
      RSV.NXT, не выходящим за окно. Реальные же сегменты можно 
      подгонять под такое предположение, отбрасывая любые их час- 
      ти, выходящие за пределы окна (включая даже сигналы SYN и 
      FIN), и осуществляяя дальнейшую их обработку только если 
      сегмент после этого начинается с номера RCV.NXT. Сегменты с 
      большими номерами в очереди сохраняются для обработки в 
      дальнейшем.
   Во-вторых, проверить бит RST.
      Состояние SYN-RECEIVED
         Если бит RST установлен, то выполнить следующие действия:
            Если данное соединение было инициировано командой пас- 
         сивного открытия - OPEN (например, был осуществлен пере- 
         ход из состояния LISTEN), то возвратить данное соединение 
         в состояние LISTEN, а управление вернуть прерванной про- 
         грамме. Нет нужды информировать обэтом пользователя. Если 
         данное соединение инициируется командой активного откры- 
         тия OEPN (например, был переход из состояние SYN-SENT), 
         то происходит отказ от этого соединения, а клиенту посы- 
         лается сообщение "connection refused". В любом случае 
         должны быть удалены все сегменты из очереди на повторную 
         посылку. Кроме того, в случае активного открытия перейти 
         в состояние CLOSED, удалить блок TCB и вернуть управление 
         прерванной программе.
      Состояния
         ESTABLISHED
         FIN-WAIT-1
         FIN-WAIT-2
         CLOSE-WAIT
            Если установлен бит RST, то все ждущие обработки за- 
         просы RECEIVE и SEND должны получить ответ "reset". 
         Убрать все сегменты из очередей. Клиенты должны получить 
         необязательное сообщение общего назначения "connection 
         reset". Перейти в состояние CLOSED, стереть блок TCB и 
         вернуть управление прерванной программе.
      Состояния
         CLOSING
         LAST-ACK
         TIME-WAIT
            Если выставлен бит RST, то перейти в состояние CLOSED, 
         удалить блок TCB и вернуть управление прерванной програм- 
         ме.
   В-третьих, проверить значение безопасности и приоритета у 
      пришедшего сегмента
      Состояние SYN-RECIEVED
            Если безопасность/закрытость и приоритет в пришедшем 
         сегменте не совпадают с безопасностью/закрытостью и прио- 
         ритетом, указанными в блоке TCB, то послать сигнал пере- 
         загрузки и возвратить управление прерванной программе.
      Состояние ESTABLISHED
            Если безопасность/закрытость и приоритет в пришедшем 
         сегменте не совпадают в точности с безопасностью/ закры- 
         тостью и приоритетом, указанными в блоке TCB, то послать 
         сигнал перезагрузки, все еще остающиеся необслуженными 
         запросы RECEIVED и SEND должны получить ответ "reset". 
         Все сегменты из очередей должны быть удалены. Клиенты 
         должны тоже получить необязательный общий сигнал 
         "connection reset". Перейти в состояние CLOSED, удалить 
         блок TCB и вернуть управление прерванной программе.
      Заметим, что данная проверка ставится после проверки номера 
   в очереди для того, чтобы предотвратить разрыв данного соедине- 
   ния, инициированный получением сегмента, оставшегося от прежне- 
   го соединения с иными безопасностью и приоритетом, существовав- 
   шего некогда между данными портами.
   В-четвертых, проверить бит SYN
      Состояния
         SYN-RECEIVED
         ESTABLISHED
         FIN-WAIT-1
         FIN-WAIT-2
         CLOSE-WAIT
         CLOSING
         LAST-ACK
         TIME-WAIT
            Если SYN находится в пределах окна, то послать сигнал 
         перезагрузки. Любые ждущие обработки команды RECEIVE и 
         SEND должны получить ответ "reset", убрать из очередей 
         все сегменты, а клиент должен получить необязательное 
         общее сообщение "connection reset". Перейти в состояние 
         CLOSED, убрать блок TCB, вернуть управление прерванной 
         программе. 
            Если SYN находится за пределами окна, то до данного 
         пункта дело не должно дойти. Еще на первом этапе (провер- 
         ка номера очереди) должно было быть послано подтвержде- 
         ние.
   В-пятых, проверить поле ACK
      Если бит ACK не установлен, то сегмент ликвидировать, а 
         управление передать прерванной программе.
      Если бит ACK установлен
         Состояние SYN-RECEIVED.
            Если SND.UNA =< SEG.ACK =< SND.NXT, то перейти в со- 
            стояние ESTABLISHED и продолжить обработку.
            Если же подтверждение в сегменте оказалось неприемли- 
            мым, то сформировать сегмент с сигналом перезагрузки
            <SEQ=SEG.ACK><CTL=RST>
            и послать его.
         Состояние ESTABLISHED
            Если SND.UNA < SEG.ACK =< SND.NXT, то установить в 
            SND.UNA значение из SEG.ACK. Любые сегменты из очереди 
            на повторную посылку, получившие при этом подтвержде- 
            ние, удаляются. Клиенты должны получить положительные 
            отзывы на буферы, которые были посланы командой SEND, 
            а ныне получили полное подтверждение (например, коман- 
            да послать буфер с данными должна завершиться сообще- 
            нием "ok"). Если подтверждение является дубликатом 
            (SEG.ACK < SND.UNA), то его можно игнорировать. Если 
            сообщение ACK подтверждает что-либо, еще не отправлен- 
            ное (SEG.ACK > SND.NXT), то послать ACK, ликвидировать 
            сегмент и вернуть управление прерванной программе.
               Если SND.UNA < SEG.ACK =< SND.NXT, то следует обно- 
            вить окно для посылки. Если (SND.WL1 < SEG.SEQ или 
            (SND.WL1 = SEG.SEQ и SND.WL2 =< SEG.ACK)), то устано- 
            вить SND.WND согласно значению SEG.WND, SND.WL1 - в 
            SEG.SEQ, SND.WL2 - в SEG.ACK.
               Заметим, что в SND.WND записано смещение относи- 
            тельно SND.UNA, xnj d SND.WL1 записан номер очереди 
            для последнего сегмента, используемого для обновления 
            SND.WND, а также, что в SND.WL2 записан номер под- 
            тверждения из последнего сегмента, используемого для 
            обновления SND.WND. При этом проверка охраняет от ис- 
            пользования устаревших сегментов для обновления окна.
         Состояние FIN-WAIT-1
               Все так же как при обработки в случае состояния 
            ESTABLISHED, но если наш сигнал FIN теперь получил 
            подтверждение, то перейти к FIN-WAIT-2 и продолжить 
            обработку в таком состоянии.
         Состояние FIN-WAIT-2
               Все так же как при обработке для случая состояния 
            ESTABLISHED, но если очередь повторной посылки пуста, 
            то команда клиента на закрытие соединения CLOSE может 
            получить подтверждение ("ok"), но при этом не удаляет 
            блока TCB.
         Состояние CLOSE-WAIT
               Делается та же обработка, что была для случая со- 
            стояния ESTABLISHED.
         Состояние CLOSING
               Все так же, как при обработке в случае состояния 
            ESTABLISHED, но если ACK в пришедшем сегменте подтвер- 
            ждает наш сигнал FIN, то перейти в состояние TIME- 
            WAIT. В противном случае сегмент игнорируется. 
         Состояние LAST-ACK
               Единственная вещь, которая может произойти в этом 
            состоянии - получение подтверждения на сигнал FIN. 
            Если наш сигнал FIN не был подтвержден, то удалить 
            блок TCB, перейти в состояние CLOSED и вернуть управ- 
            ление прерванной программе.
         Состояние TIME-WAIT
              Единственная вещь, которая может произойти в этом 
            состоянии - это повторная передача чужого сигнала FIN. 
            Подтверждить сигнал и повторно стартовать по истечении 
            контрольного времени 2MSL. 
   В-шестых, проверить бит URG
      Состояния
         ESTABLISHED
         FIN-WAIT-1
         FIN-WAIT-2
            Если бит URG установлен, то в RCV.UP занести 
         max(RCV.UP, SEG.UP), а также дать знать клиенту, что на 
         другом конце соединения имеются срочные данные, если 
         срочный указатель (RCV.UP) стоит перед данными. Если же 
         клиент уже был оповещен о данной цепочке срочных данных 
         (или если все еще находится в "режиме срочности"), не 
         следует ему напоминать об этом снова. 
      Состояния 
         CLOSE-WAIT
         CLOSING
         LAST-ACK
         TIME-WAIT
            Такого не должно произойти, поскольку был получен си- 
         гнал FIN с другого конца соединения. Игнорировать бит 
         URG.
   В-седьмых, обработать данные их сегмента
      Состояния
         ESTABLISHED
         FIN-WAIT-1
         FIN-WAIT-2
            Раз мы оказались в состоянии ESTABLISHED, то стало 
         возможным принимать текст для размещения в буферах полу- 
         чения, указанных клиентом. Текст из сегментов может пере- 
         носиться в буферы до тех пор, пока либо не наполнится 
         соответствующий буфер, либо не станет пустым сегмент. 
         Если сегмент пуст и несет флаг  проталкивания PUSH, то 
         при возврате буфера оповестить клиента о том, что был 
         получен сигнал PUSH.
            Когда протокол TCP берет на себя ответственность за 
         получение клиентом данных, то он должен также давать под- 
         тверждение факта получения этих данных. 
            Как только программа протокола TCP  принимает на себя 
         управление потоком данных, она ставит значение RCV.NXT 
         перед блоком принимаемых данных, а RCV.WND устанавливает 
         соответственно емкости буфера в данный момент. В общем 
         случае значения RCV.NXT и RCV.WND не должны корректиро- 
         ваться в меньшую сторону. 
            Отметьте, пожалуйста, что управление окном базируется 
         на предположениях, указанных в главе 3.7.
            Послать подтверждение в виде 
         <SEQ=SND.NXT><ACK=RCV.NXT><CTL=ACK>
         Данное подтверждение должно быть добавлено к уходящему на 
         другой конец соединения сегменту и, по возможности, без 
         излишних задержек.
      Состояния
         CLOSE-WAIT
         CLOSING
         LAST-ACK
         TIME-WAIT
            Такого не должно случаться, поскольку был получен си- 
         гнал FIN с другого конца соединения. Игнорировать текст в 
         сегменте.
   В-восьмых, проверить бит FIN
         Не обрабатывать сигнала FIN, если состояние CLOSED, 
      LISTEN или SYN-SENT, поскольку нет возможности проверить 
      SEG.SEQ, выкинуть пришедший сегмент и возвратить управление 
      прерванной программе.
         Если бит FIN установлен, то дать клиенту сигнал 
      "connection closing", с тем же сообщением завершить все жду- 
      щие решения запросы RECEIVED, установить RCV.NXT перед мес- 
      том в очереди сигнала FIN, послать для последнего подтверж- 
      дение. Заметим, что сигнал FIN подразумевает проталкивание 
      (PUSH) текстов во всех сегментах, еще не полученных клиен- 
      том.
      Состояния
         SYN-RECEIVED
         ESTABLISHED
            Перейти в состояние CLOSE-WAIT
      Состояние FIN-WAIT-1
            Если наш сигнал FIN получил подтверждение (возможно в 
         этом же сегменте), то перейти в состояние TIME-WAIT, за- 
         пустить контрольный таймер, отключить все иные таймеры. 
         Если подтверждения не было, перейти в состояние CLOSING.
      Состояние FIN-WAIT-2
            Перейти в состояние TIME-WAIT. Запустить контрольный 
         таймер, отключить все контрольные таймеры.
      Состояние CLOSE-WAIT
         Остаться в состоянии CLOSE-WAIT
      Состояние CLOSING
         Остаться в состоянии CLOSING
      Состояние LAST-ACK
         Остаться в состоянии LAST-ACK
      Состояние TIME-WAIT
         Остаться в состоянии TIME-WAIT. По истечении контрольного 
         времени 2MSL стартовать повторно.
      Вернуть управление прерванной программе.

Истечение контрольного времени для клиента
      Если истекло контрольного время, то в каком бы состоянии не 
   находилась программа, убрать все очереди, дать клиенту общий 
   сигнал "error: connection aborted due to user timeout", такой 
   же сигнал дать всем ждущим обработки запросам, ликвидировать 
   блок TCB, перейти в состояние CLOSED, вернуть управление прер- 
   ванной программе. 
Истечение контрольного времени для повторной посылки
      В каком бы состоянии не находилась программа, если для сег- 
   мента в очереди на повторную посылку истекло контрольное время, 
   послать этот сегмент еще раз, но уже вне очереди, произвести 
   вновь инициализацию таймера повторной посылки, вернуть управле- 
   ние прерванной программе. 
Истечение контрольного времени для состояния TIME-WAIT
      Если истекло контрольное время для состояния TIME-WAIT, то 
   ликвидировать соединение и блок TCB, перейти в состояние 
   CLOSED, вернуть управление прерванной программе.
Назад       Содержание       Вперёд