Справочник по сетевым протоколам

       

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


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

Деятельность программы протокола 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
<



/p>

Если 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 не должны корректироваться в меньшую сторону.

Послать подтверждение в виде

<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, вернуть управление прерванной программе. <


Содержание раздела