Протоколы и алгоритмы маршрутизации в Интернет

Транспортные протоколы Интернет

Разбить на страницы
Показывать лекцию целиком

Транспортными здесь называются протоколы Интернет, чьи пакеты вкладываются в IP-дейтаграммы. В этот перечень вошли UDP, все модификации TCP.

2.1. Протокол UDP

Протокол UDP (User Datagram Protocol, RFC-768) является одним из основных и старейших, расположенных непосредственно над IP. Он предоставляет прикладным процессам транспортные услуги, немногим отличающиеся от услуг протокола IP. Протокол UDP обеспечивает доставку дейтаграмм, но не требует подтверждения их получения. Он также не требует соединения с удаленным модулем UDP ("бессвязный" протокол). К заголовку IP-пакета UDP добавляет поля порт отправителя и порт получателя, которые обеспечивают мультиплексирование информации между различными прикладными процессами, а также поля длина UDP-дейтаграммы и контрольная сумма, позволяющие поддерживать целостность данных. Таким образом, если на уровне IP для определения места доставки пакета используется адрес, то на уровне UDP - номер порта.

Примерами сетевых приложений, применяющих UDP, являются NFS (Network File System), TFTP (Trivial File Transfer protocol, RFC-1350), RPC (Remote Procedure Call, RFC-1057) и SNMP (Simple Network Management Protocol, RFC-1157). Малые накладные расходы, связанные с форматом UDP, а также отсутствие необходимости подтверждения получения пакета делают этот протокол наиболее популярным при реализации приложений мультимедиа, но главное его место работы - локальные сети и мультимедиа.

Хотя протокол UDP не гарантирует доставки, по умолчанию предполагается, что вероятность потери пакета достаточно мала.

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

Например, сервер SNMP всегда ожидает сообщения, адресованного в порт 161. Если клиент SNMP желает получить услугу, он посылает запрос в UDP-порт 161 на машину, где работает сервер. На каждой машине может быть только один агент SNMP, т.к. существует только один порт 161. Данный номер порта является общеизвестным, т.е. фиксированным номером, официально выделенным в сети Internet для услуг SNMP.

Таблицы для стандартных значений номеров портов можно найти по адресу: http://book.itep.ru/4/44/udp_442.htm.

Данные, отправляемые прикладным процессом через модуль UDP, достигают места назначения как единое целое. Например, если процесс--отправитель производит 5 записей в порт, то процесс--получатель должен будет сделать 5 чтений. Размер каждого записанного сообщения будет совпадать с размером каждого прочитанного. Протокол UDP сохраняет границы сообщений, определяемые прикладным процессом. Он никогда не объединяет несколько сообщений в одно и не делит одно сообщение на части. Формат UDP-сообщений представлен ниже на рис. 2.1:

(рис 2.1) Формат UDP-дейтаграмм

Длина сообщения равна числу байт в UDP-дейтаграмме, включая заголовок. Поле UDP контрольная сумма содержит код, полученный в результате контрольного суммирования UDP-заголовка и поля данные. Нетрудно видеть, что этот протокол использует заголовок минимального размера (8 байт). Номера портов от 0 до 1024 стандартизованы. Они предназначены для серверов и использовать их в прикладных задачах не рекомендуется. С номерами портов >1024 могут работать клиенты, но и здесь нужно проявлять осторожность, так как некоторые номера портов заняты стандартными сервисами, поэтому, прежде чем использовать какой--то порт в своей программе, следует заглянуть в соответствующую базу данных IANA (http://www.iana.org/).

Модуль IP передает поступающий IP-пакет модулю UDP, если в заголовке этого пакета указан код протокола UDP. Когда модуль UDP получает дейтаграмму от модуля IP, он проверяет контрольную сумму, содержащуюся в ее заголовке. Если контрольная сумма равна нулю, это означает, что отправитель ее не подсчитал. ICMP, IGMP, UDP и TCP протоколы имеют один и тот же алгоритм вычисления контрольной суммы (RFC-1071; по модулю 1). Но вычисление контрольной суммы для UDP имеет некоторые особенности. Во--первых, длина UDP-дейтаграммы может содержать нечетное число байт, в этом случае к ней добавляется нулевой байт, который служит лишь для унификации алгоритма и никуда не пересылается. Во--вторых, при расчете контрольной суммы для UDP и TCP добавляются 12-байтные псевдозаголовки, содержащие IP-адреса отправителя и получателя, код протокола и длину дейтаграммы, которые берутся из IP-дейтаграммы (см. рис. 2.2). Как и в случае IP-дейтаграммы, если вычисленная контрольная сумма равна нулю, в соответствующее поле будет записан код 65535.

(рис 2.2) Псевдозаголовок, используемый при расчете контрольной суммы

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

Так как максимальная длина IP-дейтаграммы равна 65535 байтам, максимальная протяженность информационного поля UDP-дейтаграммы составляет 65507 байт. На практике большинство систем работает с UDP-дейтаграммами с длиной 8192 байта или менее (если, например, мы имеем дело с Ethernet, то менее 1500 байт). Детальное описание форматов, полей пакетов и пр. читатель может найти в RFC-768.

2.2. Протокол TCP

Протокол TCP (transmission control protocol, RFC-793, 1323, 1644[T/TCP], 2018, 2581, 2582[RENO], 2861, 2873, 2883[SACK], 2923[MTU], 2988[RTO], 3293[GSMP], 3448[TFRC], 3465, 3481) в отличие от UDP осуществляет доставку дейтаграмм, называемых сегментами, в виде байтовых потоков с установлением соединения. Протокол TCP применяется в тех случаях, когда требуется гарантированная доставка сообщений. Он использует контрольные суммы пакетов для проверки их целостности и освобождает прикладные процессы от необходимости таймаутов и повторных передач ради обеспечения надежности. При отслеживании подтверждения доставки в TCP реализуется алгоритм "скользящего" окна. Наиболее типичными прикладными процессами, использующими TCP, являются FTP (file transfer protocol - протокол передачи файлов) и telnet (или SSH для удаленного доступа). Кроме того, TCP используют системы SMTP, HTTP, Xwindow, RCP (remote copy), а также "r"-команды. Внутренняя структура модуля TCP гораздо сложнее структуры UDP. Подобно UDP, прикладные процессы взаимодействуют с модулем TCP через порты. Под байтовыми потоками здесь подразумевается то, что один примитив, например, read или write, может вызвать посылку адресату последовательности сегментов, которые образуют некоторый блок данных (сообщение). Применение портов открывает возможность осуществлять несколько соединений между двумя сетевыми объектами (работать с разными процессами).

Примером прикладного процесса, использующего TCP, может служить FTP, при этом будет работать стек протоколов ftp/tcp/ip/ethernet. Хотя протоколы UDP и TCP могли бы для сходных задач задействовать разные номера портов, обычно этого не происходит. Модули TCP и UDP выполняют функции мультиплексоров/демультиплексоров между прикладными процессами и IP-модулем. При поступлении пакета в модуль IP он будет передан в TCP или UDP-модуль согласно коду, записанному в поле протокола данного IP-пакета. Формат сегмента (пакета) TCP представлен ниже на рис. 2.3. Если вы хотите глубже разобраться с особенностями работы этого протокола, воспользуйтесь услугами программы tcpdump, которая позволяет отслеживать содержимое отправляемых и приходящих пакетов в ходе реализации сессии.

Если IP-протокол работает с адресами, то TCP, так же, как и UDP, - с портами. Именно с номеров портов отправителя и получателя начинается заголовок TCP-сегмента. 32-битовое поле код позиции в сообщении определяет порядковый номер первого октета в поле данных пользователя. В приложениях передатчика и приемника этому полю соответствуют 32-разрядные счетчики числа байт, которые при переполнении обнуляются. При значении флага syn=1 в этом поле лежит код ISN (Initial Sequence Number; смотри ниже описание процедуры установления связи), выбираемый для конкретного соединения. Первому байту, передаваемому через созданное соединение, присваивается номер ISN+1. Значение ISN может задаваться случайным образом. Но в UNIX 4.4BSD при загрузке ОС ISN делается равным 1 (это нарушает требования RFC), а далее увеличивается на 640000 каждые полсекунды. Аналогичная инкрементация осуществляется при установлении нового соединения. В RFC рекомендуется увеличивать счетчик ISN на 1 каждые 4 микросекунды.

32-битовое поле номер октета, который должен прийти следующим, содержит код, который на единицу больше номера последнего успешно доставленного (принятого) байта. Содержимое этого поля интерпретируется получателем сегмента, только если присутствует флаг ACK. Это поле заполняется в заголовках всех сегментов, передаваемых после установления соединения, а флаг AСK=1.

В ТСР предусмотрен режим полнодуплексной передачи. При этом данные могут передаваться в обоих направлениях независимо. В ходе обмена каждая из сторон должна отслеживать позиционные номера передаваемых и принимаемых байт. Если получен сегмент с некоторым кодом поля номер октета, который должен прийти следующим, это означает, что все октеты с номерами, меньшими указанного в данном поле, доставлены благополучно. Если благополучно доставлены байты с номерами 0-N, а затем получен сегмент с номерами байтов (N+k) - (N+k+m), такой сегмент будет буферизован, но подтверждения его получения не последует. Вместо этого посылается отклик, с кодом номер октета, который должен прийти следующим =(N+1). В случае получения сегмента с неверной контрольной суммой будет послан отклик, идентичный предыдущему. Дублированные отклики позволяют детектировать потерю пакета.

Поле HLEN определяет длину заголовка сегмента, которая измеряется в 32-разрядных словах. Это поле необходимо, так как в заголовке могут содержаться поля опций переменной длины. Далее следует поле резерв, предназначенное для будущего использования, в настоящее время должно обнуляться. Поле размер окна сообщает, сколько октетов готов принять получатель (флаг ACK=1 ) вслед за байтом, указанным в поле номер октета, который должен прийти следующим. Окно имеет принципиальное значение, оно определяет число сегментов, которые могут быть посланы без получения подтверждения. Значение ширины окна может варьироваться во время сессии. Значение этого поля, равное нулю, также допустимо и указывает, что байты вплоть до указанного в поле номер октета, который должен прийти следующим, получены, но адресат временно не может принимать данные. Разрешение на посылку новой информации может быть дано с помощью посылки сегмента с тем же значением поля номер октета, который должен прийти следующим, но ненулевым значением поля ширины окна. Поле контрольная сумма предназначено для обеспечения целостности сообщения. Контрольное суммирование производится по модулю 1. Перед контрольным суммированием к TCP-сегменту добавляется псевдозаголовок (как и в случае протокола UDP), который включает в себя адреса отправителя и получателя, код протокола и длину сегмента, исключая псевдозаголовок. Поле указатель важной информации представляет собой указатель последнего байта, содержащий информацию, которая требует немедленного реагирования. Поле имеет смысл лишь при флаге URG=1, отмечающем сегмент с первым байтом "важной информации". Значение разрядов в 6-битовом коде флаги описано в таблице 2.1. Если флаг ACK=0, значение поля номер октета, который должен прийти следующим, игнориру ется. Флаг URG=1 устанавливается в случае нажатия пользователем клавиш Del или Ctrl+С.

Значения битов поля флаги
обозначение битов (слева на право) поля флаги значение бита, если он равен 1
URG Флаг важной информации, поле Указатель важной информации имеет смысл, если urg=1
ACK Номер октета, который должен прийти следующим, правилен
PSH Этот сегмент требует выполнения операции push. Получатель должен передать эти данные прикладной программе как можно быстрее
RST Прерывание связи
SYN Флаг для синхронизации номеров сегментов, используется при установлении связи
FIN Отправитель закончил посылку байтов
(рис 2.3) Формат TCP-сегмента

Поле опции зарезервировано на будущее и в заголовке может отсутствовать, его размер переменен и дополняется до кратного 32-бит с помощью поля заполнитель. Формат поля опции представлен на рис. 2.4. В настоящее время определены опции (поле вид):

0 Конец списка опций.

1 Никаких операций. Используется для заполнения поля опции до числа октетов, кратного 4.

2 Максимальный размер сегмента (MSS).

В поле вид записывается код опции, поле LEN содержит число октетов в описании опции, включая поля вид и LEN. Определены также опции со значением вид=4,5,6,7. В предложении T/TCP (RFC-1644) описаны опции 11, 12 и 13. Поле данные может иметь переменную длину, верхняя его граница задается значением MSS (Maximum Segment Size). Значение MSS может быть задано при установлении соединения каждой из сторон независимо. Для Ethernet MSS=1452 байта.

Поле данные в TCP-сегменте может и отсутствовать, характер и формат передаваемой информации задается исключительно прикладной программой, теоретически максимальный размер этого поля составляет в отсутствии опций 65495 байт (на практике, помимо MSS, нужно помнить, например, о значении MTU для Ethernet, которое немногим больше 1500 байт). TCP является протоколом, который ориентируется на согласованную работу ЭВМ и программного обеспечения партнеров, участвующих в обмене информацией. Установление соединения клиент-сервер осуществляется в три этапа.

(рис 2.4) Формат опций для TCP-сегментов
  • Клиент посылает SYNсегмент с указанием номера порта сервера, который предлагается использовать для организации канала связи (active open).
  • Сервер откликается, посылая свой SYNсегмент, содержащий идентификатор (ISN - Initial Sequence Number). Начальное значение ISN не равно нулю. Процедура называется passive open.
  • Клиент отправляет подтверждение (ACK) получения SYN-сегмента от сервера с идентификатором равным ISN(сервера)+1.
  • Стандартная процедура установления связи представлена на рисунке 2.5 (под словом "стандартная" подразумевается отсутствие каких--либо отклонений от штатного режима, например, одновременного открывание соединения со стороны сервера и клиента). Если же соединение одновременно инициируется клиентом и сервером, в конечном итоге будет создан только один виртуальный канал.

    Префикс S на рисунке указывает на сервер, а С - на клиента. Параметры в скобках обозначают относительные значения ISN. После установления соединения ISN(S) = s_seq_1, а ISN(C) = c_seq_1.

    (рис 2.5) Алгоритм установления связи. В рамках представлены состояния клиента и сервера; (см. также рис. 2.6)

    Каждое соединение должно иметь свой неповторимый код ISN. Для реализации режима соединения прикладная программа на одном конце канала устанавливается в режим пассивного доступа ("passive open"), а операционная система на другом конце ставится в режим активного доступа ("active open"). Протокол TCP предполагает реализацию 11 состояний ( established, closed, listen, syn_sent, syn_received и т.д.; см. также RFC-793), переход между которыми строго регламентирован. Машина состояний для протокола TCP может быть описана диаграммой, представленной на рис. 2.5. Здесь состояние closed является начальной и конечной точкой последовательности переходов. Каждое соединение стартует из состояния closed. Из диаграммы машины состояний видно, что ни одному из состояний не поставлен в соответствие какой--либо таймер. Это означает, что машина состояний TCP может оставаться в любом из состояний сколь угодно долго. Исключение составляет keepalive таймер, но его работа является опционной, а время по умолчанию составляет 2 часа. Это означает, что машина состояния может оставаться 2 часа без движения. В случае, когда две ЭВМ (C и S) попытаются установить связь друг с другом одновременно, реализуется режим simultaneous connection (RFC-793). Обе ЭВМ посылают друг другу сигналы SYN. При получении этого сигнала партнеры посылают отклики SYN+ACK. Обе ЭВМ должны обнаружить, что SYN и SYN+ACK относятся к одному и тому же соединению. Когда C и S обнаружат, что SYN+ACK соответствует посланному ранее SYN, они выключат таймер установления соединения и перейдут непосредственно в состояние syn_recvd (смотри рис. 2.4).

    В состоянии established пакет будет принят сервером, если его ISN лежит в пределах s_ack, s_ack+s_wind ( s_wind - ширина окна для сервера; см. рис. 2.6). Аналогичный диапазон ISN для клиента выглядит как: c_ack, c_ack+c_wind ( c_wind ширина окна для клиента). c_wind и s_wind могут быть не равны. Пакеты, для которых эти условия не выполняются, будут отброшены.

    Рассмотрим пример установления соединения для случая FTP-запроса. Пусть клиент С запускает процесс установления FTP-соединения с сервером S. Обычный порядок установления соединения показан ниже (см. рис. 2.4):

    c > s:syn(isnc)
    s > c:syn(isns), ack(isnc)
    c > s: ack(isns) (Связь установлена)
    c > s: данные

    и/или

    s > c: данные

    ISN - идентификатор пакета, посылаемого клиентом (С) или сервером (S). Клиент, послав SYN серверу S, переходит в состояние syn_sent. При этом запускается таймер установления соединения.

    Как при установлении соединения, так и при его разрыве приходится сталкиваться с проблемой двух армий. Представим себе, что имеются две армии А и Б, причем Б больше по численности чем А. Армия Б разделена на две части, размещенные по разные стороны от армии А. Если две части армии Б одновременно нападут на армию А, победа гарантирована. В то же время нападение на А одной из частей армии Б обрекает ее на поражение. Но как обеспечить одновременность? Здесь предполагается, что радио еще не изобретено и передача сообщений осуществляется вестовыми, которые в нашем случае могут быть перехвачены врагом. Как убедиться, что вестовой дошел? Первое, что приходит в голову, это послать другого вестового с подтверждением. Но он также с некоторой вероятностью может быть перехвачен. А отправитель не будет знать, дошел ли он. Ведь если сообщение перехвачено, отправитель первичного запроса не выдаст команды на начало, так как не уверен, дошло ли его первое сообщение. Возникает вопрос, существует ли алгоритм, который бы гарантировал надежность синхронизации решений путем обмена сообщениями при ненадежной доставке? Повысит ли достоверность увеличение числа обменов между партнерами? Ответом на этот вопрос будет - нет, не существует. В этом читатель, порассуждав логически, может убедиться самостоятельно. Нетрудно видеть, что схожие проблемы возникают в любом протоколе, работающем через установление соединения. Чаще всего эта проблема решается путем таймаутов и повторных попыток (это, слава Богу, не война и все обходится без человеческих жертв).

    Сервер, получив SYN, откликается посылкой другого SYN. Когда С получает SYN от S (но не получает ACK, например, из-за его потери или злого умысла), он предполагает, что имеет место случай одновременного открытия соединения. В результате он посылает syn_ack, отключает таймер установления соединения и переходит в состояние syn_received. Сервер получает syn_ack от C, но не посылает отклика. Тогда С ожидает получения syn_ack в состоянии syn_received. Так как время пребывания в этом состоянии не контролируется таймером, С может остаться в состоянии syn_received вечно. Из--за того, что переходы из состояния в состояние не всегда четко определены, протокол TCP допускает и другие виды атак.

    Хотя TCP-соединение является полнодуплексным, при рассмотрении процесса разрыва связи проще его рассматривать как два полудуплексных канала, каждый из которых ликвидируется независимо. Сначала инициатор разрыва посылает сегмент с флагом FIN, сообщая этим партнеру, что не намерен более что--либо передавать ( FIN посылается, как правило, в результате вызова приложением функции close). Когда получение этого сегмента будет подтверждено ( ACK ), данное направление передачи считается ликвидированным (реализуется полузакрытие соединения). При этом передача информации в противоположном направлении может беспрепятственно продолжаться. Когда партнер закончит посылку данных, он также пошлет сегмент с флагом FIN. По получении отклика ACK виртуальный канал считается окончательно ликвидированным.

    Таким образом, для установления связи требуется обмен тремя сегментами, а для разрыва - четырьмя. Но протокол допускает совмещение первого ACK и второго FIN в одном сегменте, сокращая полное число закрывающих сегментов с четырех до трех.

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

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

    Состояние ESTABLISHED (рис. 2.6) указывает на то, что система находится в состоянии с установленным соединением. Четыре состояния в левом углу помещены в границы затененной зоны и соответствуют активному закрытию. Состояния CLOSE_WAIT и LAST_ACK относятся к пассивному закрытию. Переход из состояния SYN_RCVD в LISTEN возможно, если переход в SYN_RCVD осуществлен из состояния LISTEN, а не из состояния SYN_SENT (одновременное открытие двух соединений, получение RST вместо финального ACK ).

    Состояние TIME_WAIT часто называется ожиданием длительностью 2MSL (Maximum Segment Lifetime). Значение MSL задается конкретной реализацией и определяет предельную величину пребывания сегмента в сети. В RFC-793 рекомендуется задавать MSL равным 2 мин. Но нужно помнить, что ТСРсегмент транспортируется в IP-дейтаграмме, содержащей поле TTL. Когда модуль выполнил активное закрытие и в ответ на FIN послал ACK, соединение должно оставаться в состоянии TIME_WAIT в течение времени, в два раза превышающем MSL. Сокет, используемый данным соединением, не может быть задействован другим соединением в продолжение указанного времени. Все сегменты данного соединения, задержавшиеся в пути, во время TIME_WAIT отбрасываются. Этим гарантируется, что сегменты старого соединения не будут восприняты новым соединением. Такая процедура препятствует перезапуску серверов в течение 14 минут, так как в течение данного времени не могут использоваться стандартные значения номеров портов.

    (рис 2.6) Машина состояний для протокола TCP (W.R. Stivens, TCP/IP Illustrated. V1. Addison-Wesley publishing company. 1993. Имеется обновленная версия книги, переведенная на русский язык: У.Ричард Стивенс, "Протоколы TCP/IP. Практическое руководство", BHV, Санкт-Петербург, 2003)

    Состояние FIN_WAIT_2 сопряжено со случаем, когда одна сторона послала сегмент FIN, а другая сторона подтвердила его получение. Если данное соединение не нужно, можно ждать, когда приложение другой стороны получит код конца файла и пришлет свой флаг FIN. Только после этого система перейдет из состояния FIN_WAIT_2 в состояние TIME_WAIT. Теоретически такое ожидание может быть бесконечным. Другая сторона при этом остается в состоянии CLOSE_WAIT, пока приложение не вызовет функцию close. Для решения проблемы часто вводят дополнительный таймер.

    В ТСР возможна ситуация, когда обе стороны запускают процедуру закрытия одновременно (посылают FIN ), что в протоколе ТСР вполне допустимо. Каждая из сторон при этом переходит из состояния ESTABLISHED в состояние FIN_WAIT_1 (после вызова операции closed ). По получении FIN стороны переходят из состояния FIN_WAIT_1 в состояние CLOSING и посылают ACK. После получения ACK происходит переход в состояние TIME_WAIT.

    Когда оператор, работая в диалоговом режиме, нажимает командную клавишу, сегмент, в который помещается эта управляющая последовательность, помечается флагом PSH (push). Это говорит приемнику, что информация из этого сегмента должна быть передана прикладному процессу как можно скорее, не дожидаясь прихода еще какой--либо информации. Сходную функцию выполняет флаг URG. URG позволяет выделить целый массив данных, так как активизирует указатель последнего байта важной информации. Будет ли реакция на эту "важную" информацию, определяет прикладная программа получателя. URG-режим используется для прерываний при работе с FTP, telnet или rlogin. Если до завершения обработки "важной" информации придет еще один сегмент с флагом URG, значение старого указателя конца "важного" сообщения будет утеряно. Это обстоятельство должно учитываться прикладными процессами. Так, telnet в командных последовательностях всегда помещает префиксный байт с кодом 255.

    В режиме удаленного терминала (telnet/ssh) при нажатии любой клавиши формируется и посылается 41-октетный сегмент (здесь не учитываются издержки Ethernet и возможность наличия опций в IP и TCP), который содержит всего один байт полезной информации. В локальной сети здесь проблем не бывает, но в буферах маршрутизаторов в среде Интернет могут возникнуть заторы. Эффективность работы может быть улучшена с помощью алгоритма Нагля (Nagle, 1984; RFC-896). Нагль предложил при однобайтовом обмене посылать первый байт, а последующие буферизовать до прихода подтверждения получения посланного. После этого посылаются все буферизованные октеты, а запись в буфер вводимых кодов возобновляется. Если оператор вводит символы быстро, а сеть работает медленно, этот алгоритм позволяет заметно снизить загрузку канала. Встречаются, впрочем, случаи, когда алгоритм Нагля желательно отключить, например, при работе в Интернет в режиме Х-терминала, где сигналы перемещения мышки должны пересылаться немедленно, чтобы не ввести в заблуждение пользователя относительно истинного положения маркера.

    Существует еще одна проблема при пересылке данных по каналам TCP, которая называется синдром узкого окна (silly window syndrome; Clark, 1982). Такого рода проблема возникает в том случае, когда данные поступают отправителю крупными блоками, а интерактивное приложение адресата считывает информацию побайтно. Предположим, что в исходный момент времени буфер адресата полон и передающая сторона знает об этом ( window=0 ). Интерактивное приложение считывает очередной октет из TCP-потока, при этом TCP-агент адресата посылает отправителю уведомление, разрешающее ему послать один байт. Этот байт будет послан и снова заполнит до краев буфер получателя, что вызовет отправку ACK со значением window=0. Процесс может продолжаться сколь угодно долго, понижая коэффициент использования канала ниже паровозного уровня.

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

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

    В протоколе TCP "скользящее окно" служит для эффективного использования высокопроизводительных каналов с большими значениями RTT.

    Идея скользящего окна отображена на рис. 2.7. Здесь предполагается, что ширина окна равна 7 ( k=7 ; это число может меняться в очень широких пределах, обычно оно равно нескольким тысячам).

    После прихода отклика на пакет <1> окно смещается вправо на одну позицию. Теперь отправитель может послать и пакет <8>. Если порядок прихода откликов нарушается, сдвиг окна может задержаться. Размер окна в сегментах определяется соотношением:

    window > RTT*B/MSS,
    (рис 2.7) Схема использования скользящего окна

    где B - полоса пропускания канала в бит/с, MSS - максимальный размер сегмента в битах, а размер окна window - в сегментах.

    Для протокола TCP механизм скользящего окна может работать на уровне октетов или сегментов. В первом случае нужно учитывать каждый раз размер поля данных переданного и подтвержденного сегмента. В TCP протоколе используется три указателя (стрелки на рис. 2.7):

    Первый указатель определяет положение левого края окна, отделяя посланный сегмент, получивший подтверждение, от посланного сегмента, получение которого не подтверждено. Второй указатель отмечает правый край окна и указывает на сегмент, который может быть послан до получения очередного подтверждения. Третий указатель помечает границу внутри скользящего окна между уже посланными сегментами и теми, которые еще предстоит послать. Получатель организует аналогичные окна для обеспечения контроля потока данных. Если указатель 3 совпадет с указателем 2, отправитель должен прервать дальнейшее отправление пакетов до получения хотя бы одного подтверждения. Обычно получатель посылает одно подтверждение ( ACK ) на два полученных сегмента.

    Регулирование трафика в TCP подразумевает существование двух независимых процессов: контроль доставки, управляемый получателем с помощью параметра window, и контроль перегрузки, управляемый отправителем с помощью окна перегрузки cwnd (congestion window) и ssthresh (slow start threshold). Первый процесс отслеживает заполнение входного буфера получателя, второй - регистрирует перегрузку канала, а также связанные с этим потери и понижает уровень трафика. В исходный момент времени при установлении соединения cwnd делается равным одному MSS, а ssthreth=65535 байтам. Программа, управляющая пересылкой, никогда не пошлет больше байт, чем это задано cwnd и объявленным получателем значением window. Когда получение очередного блока данных подтверждено, значение cwnd увеличивается. Характер этого увеличения зависит от того, осуществляется ли медленный старт или реализуется режим подавления перегрузки. Если cwnd меньше или равно ssthreth, выполняется медленный старт,в противном случае осуществляется режим подавление перегрузки. В последнем варианте cwndi+1 = cwndi + MSS/8 +(MSS*MSS)/cwnd. Если возникает состояние перегрузки канала значение cwnd снова делается равным одному MSS.

    Окно перегрузки (cwnd) позволяет согласовать полную загрузку виртуального соединения и текущие возможности канала, минимизируя потери пакетов при перегрузке.

    В качестве модуля приращения cwnd используется MSS (а не байт). При получении подтверждения ( ACK ) окно перегрузки увеличивается на один сегмент ("медленный старт", CWNDi+1 = CWNDi + размер_сегмента; последнее слагаемое нужно, если размер окна задан в октетах, в противном случае вместо него следует использовать 1), и теперь отправитель может послать, не дожидаясь ACK, уже два сегмента и т.д.. Ширина окна, в конце концов, может стать настолько большой, что ошибка доставки в пределах окна станет заметной. Тогда будет запущена процедура "медленного старта" или другой алгоритм, который определит новое, уменьшенное значение окна. Окно перегрузки позволяет управлять информационным потоком со стороны отправителя, блокируя возможные перегрузки и потери данных в промежуточных узлах сети. Если переполнения не происходит, CWND становится больше окна, объявленного получателем, и именно последнее будет ограничивать поток данных в канале. Размер окна, объявленный получателем, ограничивается произведением полосы пропускания канала (бит/с) на RTT (время распространения пакета туда и обратно). Максимально допустимый размер окна в TCP равен 65535 байт (задается размером поля заголовка). Конечной целью регулирования трафика является установление соответствия между темпом передачи и возможностями приема. Причиной перегрузки может быть не только ограниченность размера буфера, но и недостаточная пропускная способность какого-то участка канала. С учетом этого обстоятельства каждый отправитель формирует два окна: окно получателя (window) и окно перегрузки (cwnd). Реальное значение ширины скользящего окна равно минимальному из этих величин.

    При инициализации соединения окно перегрузки имеет ширину, равную одному MSS. Отправитель посылает сегмент, и если будет прислано подтверждение получения до истечения времени таймаута, размер окна перегрузки удваивается и посылается два сегмента. При получении подтверждения доставки каждого из сегментов окно перегрузки увеличивается на один сегмент максимальной длины. Таким образом, ширина окна перегрузки последовательно удваивается, пока доставка всех сегментов подтверждается. Рост ширины окна перегрузки при этом имеет экспоненциальный характер. Именно эта процедура и называется медленным стартом (Джекобсон, 1988).

    Как было сказано выше, помимо окон перегрузки и получателя в TCP используется третий параметр - порог (иногда он называется порогом медленного старта ssthresh). При установлении соединения ssthresh=64 Kбайт. В случае возникновения таймаута значение ssthresh делается равным CWND/2, а само значение CWND приравнивается одному MSS (см. рис. 2.8). Далее запускается процедура медленного старта, чтобы выяснить возможности канала. При этом экспоненциальный рост cwnd осуществляется вплоть до значения ssthresh. Когда этот уровень cwnd достигнут, дальнейший рост происходит линейно с приращением на каждом шагу равным MSS (рис. 2.8).

    (рис 2.8) Эволюция ширины окна при медленном старте

    Здесь предполагается, что MSS=1 Кбайт. Началу диаграммы соответствует установка значения ssthresh=16 Kбайт. Данная схема позволяет более точно выбрать значение cwnd. Заметим, что в разных реализациях в качестве единицы измерения для cwnd и ssthresh может использоваться число байт или число сегментов. После таймаута, который на рисунке произошел при передаче c номером 12, значение порога понижается до 12 Кбайт ( =cwnd/2 ). Ширина окна cwnd снова начинает расти от передачи к передаче, начиная с одного сегмента, вплоть до нового значения порога ssthresh=12 Кбайт. Стратегия с экспоненциальным и линейным участками изменения ширины окна перегрузки позволяет несколько приблизить среднее его значение к оптимальному. Для локальных сетей, где значение RTT невелико, а вероятность потери пакета мала, оптимизация задания cwnd не так существенна, как в случае протяженных внешних (например, спутниковых) каналов. Ситуация может поменяться, если в локальной сети имеется участок, где вероятность потери пакетов велика. Таким участком может быть МАСбридж (или переключатель), один из каналов которого подключен к сегменту Fast Ethernet, а другой к обычному Ethernet на 10 Мбит/c. Если такой мост не снабжен системой подавления перегрузки (до сих пор такие приборы не имели подобных систем), то каждый из пакетов будет потерян в среднем 9 раз, прежде чем будет передан (здесь предполагается, что передача идет из сегмента FE). При этом cwnd будет практически все время равно MSS, что крайне неэффективно при передаче по каналам Интернет. Такие потери вызовут определенные ошибки при вычислении среднего значения и дисперсии RTT, а как следствие и величин таймаутов. Применение в таких местах маршрутизаторов или других приборов, способных реагировать на перегрузку посредством ICMP(4), решает эту проблему (беда в том, что многие ТСР агенты не реагируют на ICMP(4)). Алгоритм медленного старта придуман как раз для преодоления подобных проблем, так как он минимизирует потери, сопряженные с переполнением буферов.

    Для взаимного согласования операций в рамках TCP-протокола используется четыре таймера.

  • Таймер повторных передач (retransmission; RTO) контролирует время прихода подтверждений ( ACK ). Таймер запускается в момент посылки сегмента. При получении отклика ACK до истечения времени таймера - он сбрасывается. Если же время таймера истекает до прихода ACK, сегмент посылается адресату повторно, а таймер перезапускается.
  • Таймер запросов (persist timer), контролирующий размер окна даже в случае, когда приемное окно закрыто. При window=0 получатель при изменении ситуации посылает сегмент с ненулевым значением ширины окна, что позволит отправителю возобновить свою работу. Но если этот пакет будет потерян, возникнет тупик, тогда каждая из сторон ждет сигнала от партнера. Именно в этой ситуации и используется таймер запросов. По истечении времени этого таймера отправитель пошлет сегмент адресату. Отклик на этот сегмент будет содержать новое значение ширины окна. Таймер запускается каждый раз, когда получен сегмент с window=0.
  • Таймер контроля работоспособности (keepalive), который регистрирует факты выхода из строя или перезагрузки ЭВМ-партнеров. Время по умолчанию равно 2 часам. Keepalive-таймер не является частью TCP-спецификации. Таймер полезен для выявления состояний сервера halfopen при условии, что клиент отключился (например, пользователь выключил свою персональную ЭВМ, не выполнив LOGOUT ). По истечении времени таймера клиенту посылается сегмент проверки состояния. Если в течение 75 секунд не будет получен отклик, сервер повторяет запрос 10 раз с периодом 75 сек, после чего соединение разрывается. При получении любого сегмента от клиента таймер сбрасывается и запускается вновь.
  • 2MSL-таймер (Maximum Segment Lifetime) контролирует время пребывания канала в состоянии TIME_WAIT. Выдержка таймера по умолчанию равно 2 мин (FIN_WAITтаймер). См. рис. 2.6. и RFC-793. Таймер запускается при выполнении процедуры active close в момент посылки последнего ACK.
  • Важным параметром, определяющим рабочие параметры таймеров, является RTT (время путешествия пакета до адресата и обратно). TCPагент самостоятельно измеряет RTT. Такие измерения производятся периодически, и по их результатам корректируется среднее значение RTT:

    RTTm = a*RTTm + (1-a)*RTTi,

    где RTTi - результат очередного измерения, RTTm - величина, полученная в результате усреднения предыдущих измерений, а - коэффициент сглаживания, обычно равный 0.9. RFC-793 рекомендует устанавливать время таймаута для ретрансмиссии RTO (Retransmission TimeOut) равным RTO=RTTm*b, где b равно 2. От корректного выбора этих параметров зависит эффективная работа каналов. Так, занижение времени ретрансмиссии приводит к неоправданным повторным посылкам сегментов, перегружая каналы связи. Для более точного выбора RTO необходимо знать дисперсию RTT. Несколько более корректную оценку RTO можно получить из следующих соотношений (предложено Джекобсоном в 1988 году, он же позднее предложил целочисленный алгоритм реализации этих вычислений):

    RTTm = RTTm + g(RTTi - RTTm)

    D = D + d(|RTTi - RTTm | - D)

    RTO = RTTm + 4D,

    где D - среднее отклонение RTT от равновесного значения, а коэффициенты g = 0,125, d = 0,25. Чем больше g, тем быстрее растет RTO по отношению к RTT. Это хорошо работает до тех пор, пока не произойдет таймаут и ретрансмиссия. В этом случае, получив ACK, трудно решить, какому сегменту соответствует это подтверждение, первому или второму. На эту проблему впервые обратил внимание Фил Карн. Решением проблемы является приостановка коррекции RTTm при таймауте и ретрансмиссиях. Значение RTO зависит от пропускной способности канала и от специфических задержек, например, в случае спутниковых каналов. В основном RTO лежит в секундном диапазоне (515 сек). Наиболее вероятная причина потери пакетов - это перегрузка канала на участках между отправителем и приемником. Указанием на то, что пакет потерян, может служить таймаут или получение дубликата сегмента ACK. Если произошел таймаут, система переходит в режим "медленного старта" (ширина окна перегрузки делается равной 1 сегменту, а значение порога медленного старта - ssthresh делается равным половине cwnd, при котором это произошло). Дублирование ACK иницирует потерю пакета до наступления таймаута. В этом случае сначала меняется алгоритм приращения величины окна перегрузки cwnd (замедляется темп его роста). После прихода очередного ACK новое значение cwnd вычисляется по формуле:

    cwndi+1 = cwndi + (размер_сегмента*размер_сегмента)/cwndi + размер_сегмента/8

    Если же в этот момент величина окна перегрузки меньше или равна некоторому порогу ( ssthresh - slow start threshold, обычно измеряется в байтах), осуществляется "медленный старт". Следует помнить, что TCP требует посылки немедленного подтверждения (дублированного ACK ) при обнаружении прихода сегментов с нарушением порядка следования. Причиной нарушения порядка следования может быть флуктуация задержки в сети или потеря пакета. Если получено три или более задублированных ACK, что является убедительным указанием на потерю пакета, не дожидаясь таймаута, осуществляется повторная передача. Перехода в режим медленного старта в этом случае не производится, но понижаются значения cwnd и ssthresh (почти вдвое).

    Когда TCP-канал закрывается и за время сессии переслано более 16 полых окон, а адресат достижим не через маршрут по умолчанию, то в таблицу маршрутизации заносится следующая информация: усредненное значение RTT, значение дисперсии RTT и ssthresh.

    Если в ходе TCP-сессии получено сообщение ICMP(4) (переполнение канала - quench), требующее снижения потока данных, то cwdn делается равным одному сегменту, а величина порога медленного старта ssthresh не изменяется. На ICMP-сообщения о недостижимости сети или ЭВМ программы TCP-уровня не реагируют.

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

    Будучи однажды создан, канал TCP может существовать "вечно". Если клиент и сервер пассивны, они не заметят того, например, что какой-то бульдозер оборвал кабель или что спутник связи покоится на дне океана. Чтобы это обнаружить, либо клиент, либо сервер должны попытаться послать какуюто информацию. Чтобы информировать систему об этих и подобных им жизненных неурядицах, предусмотрен таймер контроля работоспособности (keepalive). Многим читателям, возможно, приходилось легкомысленно выключать питание своего персонального компьютера, не позаботившись о корректном logout из процедуры ssh или FTP. Если бы не существовало этого таймера, то, включив ЭВМ, вы бы обнаружили, что "находитесь" в заморском депозитарии, где были вчера. Но таймер контроля работоспособности может и прервать сессию, если какой-то промежуточный маршрутизатор произвел перезагрузку или был вынужден поменять маршрут. Принцип работы таймера работоспособности предельно прост. Если канал пассивен, например, 2 часа, сервер посылает клиенту сегмент-зонд. При этом ЭВМклиент может быть в одном из четырех состояний.

  • Работоспособен и достижим для сервера. Отклик от клиента сбросит таймер работоспособности в ноль (начало отсчета очередных двух часов).
  • Вышел из строя, выключен или перезагружается. Сервер посылает 10 запросов с интервалом 75 сек. Если отклика нет, канал закрывается и со стороны сервера.
  • Перезагрузился. Сервер получит отклик типа RESET, и канал будет закрыт.
  • Работоспособен, но не достижим для сервера. Случай тождественен описанному во втором по порядку пункте.
  • Временная постоянная таймера keepalive является системной переменной единой для всех пользователей ЭВМ или даже локальной сети.

    Расширение пропускной способности и надежности телекоммуникационных каналов делает актуальной совершенствование протоколов. Так как TCP является основным транспортным протоколом, попытки усовершенствовать его предпринимаются, начиная с 1992 года (RFC-1323, Якобсон, Браден и Борман; см. также ссылки в конце главы). Целью этих усовершенствований служит повышение эффективности и пропускной способности канала, а также обеспечение безопасности. При этом рассматриваются следующие возможности:

  • увеличение MTU (максимальный передаваемый блок данных);
  • расширение окна за пределы 65535 байт;
  • исключение "трехсегментного" процесса установления связи и "четырехсегментного" ее прерывания (T/TCP, RFC-1644);
  • совершенствование механизма измерения RTT ;
  • оптимизация отслеживания CWND.
  • Оптимальный выбор MTU позволяет минимизировать или исключить фрагментацию (и последующую сборку) сегментов. Верхняя граница на MTU налагается значением MSS (максимальный размер сегмента). Разумно находить и запоминать оптимальные значения MTU для каждого конкретного маршрута. Так как в современных системах используются динамические протоколы маршрутизации, поиск оптимального MTU рекомендуется повторять каждые 10 мин (RFC-1191).

    Как уже отмечалось, размер TCP-окна определяется произведением полосы канала (в бит/с) на RTT в сек. Современный уровень технологий требует увеличения максимально возможного размера окна в 10100 раз. Протокол же разрешает всего 65535 байт. Появление мощных каналов порождает и другие проблемы - потеря пакетов в них обходится слишком дорого, так как "медленный старт" и другие связанные с этим издержки сильно снижают пропускную способность. В последнее время алгоритм медленного старта заменяется более эффективными алгоритмами.

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

    Существуют и другие, могущие показаться забавными проблемы. Каждый сегмент в TCP-протоколе снабжается 32-битным идентификатором. Время жизни IP-пакета (TTL) определяется по максимуму 255 шагами или 255 секундами в зависимости от того, что раньше наступит. Трудно предсказуемая ситуация может произойти, когда канал ликвидирован, затем создан снова (для той же комбинации IP-адресов и портов), а какой-то пакет из предшествующей сессии, погуляв по Интернет, придет уже во время следующей. Есть ли гарантия, что он будет верно идентифицирован? Одной из мер, упомянутых ранее, можно считать использование ограничения по максимальному времени жизни сегмента (MSL) или TTL, хотя снижение значения TTL не всегда возможно - ведь IP-пакетами пользуется не только TCP-протокол и нужна очень гибкая система задания его величины. Во многих приложениях MSL=30 сек (рекомендуемое значение 2 мин слишком велико). Технический прогресс ставит и некоторые новые проблемы. Высокопроизводительные каналы ( $$\ge 1$$ Гбит/с) уже сегодня могут исчерпать разнообразие идентификационных кодов пакетов за один сеанс связи. Появление же двух пакетов с равными идентификаторами может породить неразрешимые трудности. Для передачи мегабайтного файла по гигабитному каналу требуется около 40 мсек (при этом предполагается, что задержка в канале составляет 32 мсек ( RTT=64 мсек)). Собственно передача этой информации занимает 8 мсек. Из этих цифр видно, что традиционные протоколы, размеры окон и пр. могут свести на нет преимущества скоростного (дорогостоящего) канала. Пропускная способность такого канала определяется уже не его полосой, а задержкой. Понятно также, что необходимо расширить поле размера окна с 16 до 32 бит. Чтобы не изменять формат TCPсегментов, можно сделать код размера окна в программе 32-разрядным, сохранив соответствующее поле в сегменте неизменным. Размер окна в этом случае задается как бы в формате с плавающей запятой. При установлении канала определяется масштабный коэффициент n (порядок) лежащий в интервале 0-14. Передача этого коэффициента (один байт) осуществляется сегментом SYN в поле опций. В результате размер окна оказывается равным 65535*2n. Если один из партнеров послал ненулевой масштабный коэффициент, но не получил такого коэффициента от своего партнера по каналу, то n считается равным нулю. Эта схема позволит сосуществовать старым и новым системам. Выбор n возлагается на TCP-модуль системы.

    Чтобы точнее отслеживать вариации RTT, предлагается помещать временные метки в каждый посылаемый сегмент. Так как в TCP используется одно подтверждение ACK на несколько сегментов, правильнее будет сказать, что RTT измеряется при посылке каждого ACK. Способность и готовность партнеров работать в таком режиме временных меток определяется на фазе установления канала. Более точное вычисление RTT позволяет не только корректно выбрать временные постоянные для таймеров, правильно вычислить задержку TIME_WAIT ( TIME_WAIT=8*RTO ), но и отфильтровать "старые" сегменты. Идеология временных меток применяется и в алгоритме PAWS (Protection Against Wrapped Sequence Numbers) для защиты против перепутывания номеров сегментов.

    Предлагаемое усовершенствование TCP - T/TCP модифицирует алгоритмы выполнения операций. T/TCP вводит новую 32-битную системную переменную: число соединений ( CC ). СС позволяет сократить число пересылаемых сегментов при установлении канала, а также отфильтровывать "старые" сегменты, не принадлежащие данной сессии (установленной связи). Время отклика клиента в рамках указанных алгоритмов сокращается до суммы RTT и времени обработки запроса процессором. Данные пришедшие до SYN-сегмента должны буферизоваться для последующей обработки, а не отбрасываться.

    Как уже отмечалось, максимальная длина сегмента (MSS - Maximum Segment Size) в TCP-обменах величина переменная. Длина сегмента определяет длину кадра, в который он вложен. Для локальных Ethernet-сетей MSS=1460 октетов. Чем длиннее кадр, тем выше пропускная способность сети (меньше накладные расходы на заголовок кадра). С другой стороны, при передаче дейтаграмм по внешним каналам, где MTU не столь велик, большое значение MSS приведет к фрагментации пакетов, которая замедлит обмен, поэтому администратор сети должен взвешивать последствия, задавая значения размера сегментов. Если MSS явно не задан, устанавливается значение по умолчанию (536 байт), что соответствует 576-байтной IP-дейтаграмме. Для нелокальных адресов это, как правило, считалось разумным выбором. Следует, впрочем, заметить, что технология идет вперед и MTU для региональных соединений уже превышает 1500 байт.

    2.2.1 Модели реализации протокола TCP и его перспективы

    Как известно протокол TCP (описание протокола смотри, например, в [2.38]) ориентирован на соединение, он использует для транспортировки IP-дейтаграммы (L3), которые пересылаются посредством протокольных кадров уровня L2. Между двумя партнерами может быть прямое соединение, а может располагаться большое число сетевых приборов уровней L2 и L3 (см. рис. 2.9). Если потоки входящих и выходящих сегментов для заданного сетевого устройства равны, режим стационарен и состояние его буферов не меняется. Но маршрутизаторы и переключатели обычно являются многоканальными устройствами. По этой причине, если даже партнеры ТСР-соединения рассчитаны на идентичную скорость обмена, возможна ситуация, когда некоторое сетевое устройство, вовлеченное в обмен, окажется перегруженным. Ведь всегда могут возникать и исчезать новые сессии информационного или мультимедийного обмена, использующие частично те же сетевые устройства. Протокол ТСР функционирует нормально при выполнении ряда условий.

  • Вероятность ошибки доставки (BER) невелика, и потеря пакета вероятнее всего происходит из-за переполнения буфера. Если потеря пакета из-за его искажения существенна, понижение CWND не поможет, и пакеты будут теряться с той же вероятностью (здесь было бы уместно поискать оптимальное значение MTU ).
  • Время доставки ( RTT ) достаточно стабильно, и для его оценки можно использовать простые линейные аппроксимации. Здесь подразумевается, что в рамках сессии все пакеты следуют одним и тем же путем и смена порядка прихода пакетов, хотя и допускается, но маловероятна. Разрешающая способность внутренних часов отправителя должна быть достаточно высока, в противном случае возникают серьезные потери из-за таймаутов.
  • Сеть имеет фиксированную полосу пропускания и, во всяком случае, не допускает скачкообразных ее вариаций. В противном случае потребовался бы механизм для прогнозирования полосы пропускания, а действующие алгоритмы задания CWND оказались бы не эффективными.
  • Буферы сетевых устройств используют схему первый_вошел-первым_вышел (FIFO). Предполагается, что размер этих буферов соответствует произведению RTT*B ( B - полоса пропускания, RTT - сумма времен транспортировки сегмента от отправителя к получателю и времени движения отклика от получателя к отправителю). Если последнее условие нарушено, пропускная способность неизбежно понизится и будет определяться размером буфера, а не полосой пропускания канала.
  • Длительность TCP-сессии больше нескольких RTT, чтобы оправдать используемую протокольную избыточность. Короткие ТСР-сессии, широко используемые WEB-технологией снижают эффективность обмена. (Именно это обстоятельство вынудило в версиях HTTPv1.1 и выше не разрывать ТСР-соединение после вызова очередной страницы).
  • Чтобы минимизировать влияние избыточности, связанной с заголовком ( 20 байт IP +20 байт ТСР + МАС-заголовок ), используемое поле данных должно иметь большой объем. Для узкополосных каналов, где MTU мало, нарушение данного требования делает канал низкоэффективным. По этой причине выявление допустимого MTU в начале сессии должно приветствоваться.
  • Взаимодействие с другими ТСР-сессиями не должно быть разрушительным, приводящим к резкому снижению эффективности виртуального канала.
  • Конечно, данные условия выполняются отнюдь не всегда, и система не рухнет, если эти условия нарушаются часто. Но эффективность работы соединения окажется не оптимальной. Примером ситуации, когда перечисленные условия нарушаются сразу по нескольким позициям, может служить мобильная IP-связь и работа через спутниковые каналы.

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

    Для прояснения модели работы протокола ТСР рассмотрим простой фрагмент сети, отображенный на рис. 2.9.

    (рис 2.9)

    На данном рисунке ЭВМ С1С3 могут осуществлять обмен друг с другом и с ЭВМ С4С6. Переключатели SW работают на уровне L2 имеют буферы и могут быть причиной потерь, так же, как сами ЭВМ и маршрутизаторы GW1-GW2. Понятно, что объектом перегрузки, помимо названных устройств, может стать любой сетевой объект сети Интернет. Если устройства L3 при переполнении своего буфера могут послать отправителю пакета уведомление ICMP(4), то SW в общем случае могут этого и не делать (например, потому что не умеют). Причиной потери может быть и повреждение пакета на безбрежных просторах Интернет. Особые проблемы могут порождать каналы с большим произведением полосы на RTT [2.3]. В основных версиях протокола ТСР для подавления перегрузки используется механизм окон, который управляется потерей пакетов. В современных сетях передача данных, которая создает стационарный трафик, сосуществует с мультимедиа трафиком, который по своей природе нестабилен, что создает дополнительные проблемы для управления с применением оконных алгоритмов. Кроме того, мультимедийный трафик транспортируется обычно протоколом UDP, не предполагающим подтверждений доставки. Именно дейтаграммы UDP могут вызвать переполнение буфера, и об этом станет известно отправителю позднее, после регистрации потери ТСР сегмента.

    Анализируя различные модели работы протокола ТСР, следует учитывать, что в сети Интернет могут встречаться участки с разными протоколами L2 (Ethernet, ATM, SDH, Frame Relay, PPP и т.д.). Эти технологии имеют разные алгоритмы обработки ситуаций перегрузки (или не имеют их вовсе), а отправитель и получатель, как правило, не имеют данных о том, какие протоколы уровня L2 реализуют виртуальное соединение (L4).

    В настоящее время предложено и опробовано несколько разновидностей протокола TCP.

    2.2.1.1. TCP-reno

    В TCP-reno [17, 1990г; RFC-2581] при нормальной ситуации размер окна меняется циклически. Размер окна увеличивается до тех пор, пока не произойдет потеря сегмента. TCP-reno имеет две фазы изменения размера окна: фаза медленного старта и фаза избежания перегрузки. При получении отправителем подтверждения доставки в момент времени t + tA [сек] текущее значение размера окна перегрузки cwnd(t) преобразуется в cwnd(t + tA) согласно (1):

    $$cwnd(t+t_A)= \begin{cases} \text{фаза медленного старта:}\\ cwnd(t) +1, \text{ } f \text{ } cwnd(t) < ssth(t)\\ \text{фаза исключения перегрузки}\\ cwnd(t) +\frac{1}{cwnd(t)}, \text{ } f \text{ } cwnd(t) \ge ssth(t) \end{cases}$$

    где ssth(t) [пакетов] - значение порога, при котором TCP переходит из фазы медленного старта в фазу исключения перегрузки. Когда в результате таймаута детектируется потеря пакета, значения cwnd(t) и ssth(t) обновляются следующим образом:

    cwnd(t)=1; ssth(t)=(cwnd(t))/2;

    С другой стороны, когда TCP детектирует потерю пакета согласно алгоритму быстрой повторной передачи, cwnd(t) и ssth(t) обновляются иначе:

    ssth(t) = (cwnd(t))/2; cwnd(t)= ssth(t);

    TCP-reno после этого переходит в фазу быстрого восстановления. В этой фазе размер окна увеличивается на один пакет, когда получается дублированное подтверждение. С другой стороны, cwnd(t) делается равным ssth(t), когда приходит недублированный отклик для пакета, посланного повторно. В случае таймаута ssth(t)= (cwnd(t))/2; cwnd=1 (смотри описание алгоритма TCP-Tahoe).

    Результаты моделирования показывают, что каждое соединение обычно теряет около двух пакетов в каждом эпизоде перегрузки. Потери случаются, когда буфер полон и одно соединение увеличивает размер окна на единицу. Когда ячейки из этого нового пакета приходит в буфер, они обычно вызывают потерю ячеек, принадлежащих двум пакетам (конец пакета, пришедшего из другого соединения, и начало следующего). Итак, в среднем следует ожидать потерю трех пакетов на одно столкновение. В нашем примере двух соединений с RTT 40 мсек и 80 мсек, раз буфер полон и произошло столкновение, эпизод перегрузки длится 40 мсек. За время этого периода 80 мсек соединение увеличивает свое окно грубо 50% времени. То есть среднее число потерянных пакетов из-за этого увеличивается в 1.5 раза. Следовательно, всего 4.5 пакетов, или 2.25 пакетов на соединение теряется в среднем на один эпизод перегрузки.

    В настоящее время наиболее популярной является модель NewReno, изложенная в документе RFC-3782 (апрель 2004 года), и использующая алгоритм Fast Retransmit Fast Recovery (быстрая повторная пересылка и быстрое восстановление). В случае, когда доступна опция выборочного подтверждения (SACK), отправитель знает, какие пакеты следует переслать повторно на фазе быстрого восстановления (Fast Recovery). В отсутствие опции SACK нет достаточной информации относительно пакетов, которые нужно послать повторно. При получении трех дублированных подтверждений (DUPACK) отправитель считает пакет потерянным и посылает его повторно. После этого отправитель может получить дополнительные дублированные подтверждения, так как получатель осуществляет подтверждение пакетов, которые находятся в пути, когда отправитель перешел в режим Fast Retransmit. В случае потери нескольких пакетов из одного окна отправитель получает новые данные, когда приходит подтверждение для повторно посланных пакетов. Если потерян один пакет и не было смены порядка пакетов, тогда подтверждение этого пакета будет означать успешную доставку всех предыдущих пакетов до перехода в режим Fast Retransmit. Однако если потеряно несколько пакетов, тогда подтверждение повторно посланного пакета подтверждает доставку некоторых, но не всех пакетов, посланных до перехода в режим быстрой повторной пересылки (Fast Retransmit). Такие подтверждения называются частичными (смотри также http://www.acm.org/sigcomm/sigcomm96/ program.html).

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

    Алгоритм NewReno использует переменную recover (восстановление), исходное значение которой равно исходному порядковому номеру пакета. Рассмотрим узловые этапы реализации алгоритма.

  • Три задублированных ACK.

    Когда отправителю приходят три задублированных ACK, а он не находится в состоянии Fast Recovery, проверяется, перекрывает ли поле Cumulative Acknowledgement больший диапазон, чем задано переменной recover. Если это так, то исполняется операция 1A. В противном случае - 1B.

    1A) Запуск Fast Retransmit.

    Если система находится в этом режиме, ssthresh делается равным значению не большему, чем задано уравнением 1. (Это уравнение 3 из [RFC-2581]).

    ssthresh = max (FlightSize / 2, 2*SMSS)     (1)

    где FlightSize - объем доставляемых данных в сети. Кроме того, переменная recover делается равной наибольшему порядковому номеру переданного пакета, и осуществляется переход к пункту 2.

    1B) Без быстрой повторной передачи.

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

  • Вход в режим быстрой повторной передачи.

    Передается потерянный сегмент и устанавливается cwnd равным ssthresh плюс 3*SMSS. Это искусственно увеличивает окно перегрузки на несколько сегментов (три), которые покинули сеть и буферизованы получателем (SMSS - MSS отправителя).

  • Быстрое восстановление.

    Для каждого нового дублированного ACK, полученного в режиме быстрого восстановления, cwnd увеличивается на SMSS. Это искусственно увеличивает окно перегрузки, чтобы учесть сегмент, который покинул сеть.

  • Быстрое восстановление, продолжение.

    Сегмент передается, если это разрешено новым значением cwnd и значением window, объявленным получателем.

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

    Полное подтверждение.

    Если ACK подтверждает все данные вплоть до позиции, указанной переменной recover, тогда ACK подтверждает получение промежуточных сегментов, начиная с передачи потерянного сегмента и получения тройного дублированного ACK. cwnd устанавливается либо (1) min (ssthresh, FlightSize + SMSS) либо (2) ssthresh, где ssthresh равно значению, установленному на этапе 1; это называется снижением ("сдутием") значения окна. Заметим, что FlightSize ( FlightSize - объем посланных, но еще не подтвержденных данных) на этапе 1 относится к объему данных, не доставленных на этапе 1, когда произошел переход в режим быстрого восстановления, в то время как FlightSize на этапе 5 относится к объему данных, не доставленных на этапе 5, когда произошел выход из режима быстрого восстановления. Если выбрана вторая опция, реализации разрешено принять меры, чтобы избежать возможного всплеска информационного потока, в случае, когда объем недоставленных данных в сети много меньше, чем допускает окно перегрузки. Простым механизмом является ограничение числа информационных пакетов, которые могут быть посланы в ответ на одно подтверждение; это в программе моделирования NS называется "maxburst_".

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

    Если это ACK в действительности не подтверждает доставку всех данных вплоть до позиции, заданной recover включительно, тогда это частичное ACK. В этом случае передается первый неподтвержденный сегмент. Снижается значение окна перегрузки с учетом объема новых данных, подтвержденных с использованием поля группового подтверждения. Если частичное ACK подтверждает как минимум один SMSS данных, тогда к окну перегрузки добавляется SMSS байт. Так же, как на этапе 3, это искусственно увеличивает окно перегрузки, чтобы учесть сегмент, который покинул сеть. Посылается новый сегмент, если это разрешено новым значением cwnd. Это "частичное сокращение окна" пытается гарантировать, что, когда режим быстрого восстановления в конце концов завершится, объем недоставленных данных будет примерно равен ssthresh. Выхода из режима быстрого восстановления не производится (т.e., если позднее придет какой--либо задублированный ACK, выполняются шаги 3 и 4).

    Для первого частичного ACK, который приходит во время реализации быстрого восстановления, сбрасывается таймер повторной передачи.

  • Таймауты повторной передачи.

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

  • Этап 1 специфицирует проверку того, что поле кумулятивного подтверждения покрывает больший диапазон, чем это задано переменной recover. Так как поле подтверждения содержит порядковый номер, который получатель ожидает получить, "ack_number" подтверждения покрывает больший диапазон номеров, чем recover, когда:

    ack_number - 1 > recover;

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

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

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

    Другим вариантом реакции на частичное подтверждение может быть повторная посылка более чем одного пакета и сброс таймера повторной пересылки после повторной передачи. В случае множественных потерь пакетов повторная посылка двух пакетов при получении частичного подтверждения обеспечивает более быстрое восстановление системы. Такой подход требует меньше времени, чем N RTT в случае потери N пакетов. Однако при отсутствии опции SACK медленный старт обеспечивает достаточно быстрое восстановление системы без пересылки лишних пакетов.

    TCP отправитель реагирует на частичные ACK сокращением окна перегрузки на величину, соответствующую объему подтвержденных данных, возвращая назад SMSS байт, если частичное ACK подтверждает, по крайней мере, SMSS байт новых данных, и посылая новый сегмент, если это допускается новым значением cwnd. Таким образом, посылается только один отправленный ранее пакет в ответ на каждое частичное подтверждение, но могут быть посланы и новые пакеты, в зависимости от объема подтвержденной частично доставки. Напротив, в варианте NewReno, описанном в (Fall, K. and S. Floyd, "Simulationbased Comparisons of Tahoe, Reno and SACK TCP", Computer Communication Review, July 1996. URL ftp://ftp.ee.lbl.gov/papers/sacks.ps.Z), в случае частичного подтверждения устанавливается значение окна перегрузки, равное ssthresh. Такой подход является более консервативным, и не пытается точно определить число недоставленных пакетов после получения частичного подтверждения.

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

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

    Алгоритм, описанный в RFC-3782, соответствует варианту Careful алгоритма NewReno TCP из RFC-2582 и исключает проблему множественных повторных пересылок. Этот алгоритм использует переменную recover, значение которой соответствует исходному порядковому номеру посланного пакета. После каждого таймаута повторной передачи, наибольший порядковый номер переданного пакета записывается в переменную recover.

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

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

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

    2.2.1.2. TCP Vegas

    TCP-Vegas [9, 1994г] контролирует размер окна путем мониторирования отправителем RTT для пакетов, посланных ранее. Если обнаруживается увеличение RTT, система узнает, что сеть приближается к перегрузке, и сокращает ширину окна. Если RTT уменьшается, отправитель определит, что сеть преодолела перегрузку, и увеличит размер окна. Следовательно, размер окна в идеальной ситуации будет стремиться к требуемому значению. В частности, на фазе исключения перегрузки размер окна будет равен

    $$cwnd(t+t_A)= \begin{cases} cwnd(t)+1,\text{ }\text{ } f \text{ }\text{ } diff<\frac{\alpha}{base \_rtt}\\ cwnd(t.) \text{ }\text{ } \frac{\alpha}{base \_rtt}\le diff \le \frac{\beta}{base \_rtt}; \text{ }\text{ }diff=\frac{cwnd(t)}{base \_rtt}-\frac{cwnd(t)}{rtt}\\ cwnd(t)-1,\text{ }\text{ } \frac{\beta}{base \_rtt}<diff text{ } \end{cases}$$

    где rtt [сек] - зарегистрированное RTT, base_rtt [сек] - наименьшее встретившееся в данном цикле RTT, а $$\alpha$$ и $$\beta$$ - некоторые константы (смотри также [2.3]). Эта модификация ТСР требует высокого разрешения таймера отправителя.

    2.2.1.3. TCP-Tahoe

    Алгоритм TCP-Tahoe является наиболее старым и широко распространенным [2.16]. Этот алгоритм был сформулирован Джакобсоном в 1988 году, некоторые коррекции были внесены в него позднее.

    Если буфер переполнен, какое-то число сегментов будет потеряно. При этом может быть запущено несколько сценариев. Основной вариант - медленный старт, он запускается в рамках классического алгоритма ТСР-Tahoe при потере сегмента и сопряженном с ним таймаутом ( RTO ) у отправителя, так как отправитель не получит сигнала подтверждения ACK для потерянного сегмента. Медленный старт предполагает установку окна перегрузки ( CWND ) равным 1, а порога медленного старта ( ssthresh ) - равным половине значения CWND, при котором произошел таймаут. Сокращение CWND до единицы происходит потому, что отправитель не имеет никакой информации о состоянии сети. Далее после каждого подтверждения CWNDi+1 = CWNDi+1. Эта формула работает до тех пор, пока CWND не станет равным ssthresh. После этого рост CWND становится линейным (смотри формулу 1). Смысл этого алгоритма заключается в удержании значения CWND в области максимально возможных значений. По существу, эта оптимизация осуществляется с помощью потери пакетов. Если потери пакетов не происходит, значение CWND достигает значения window по умолчанию, задаваемого при конфигурации ТСР-драйвера. На рис. 2.10 показана эволюция CWND при потере пакетов.

    (рис 2.10)

    Значение таймаута вычисляется по формуле:

    $$RTO=\overline{RTT}+4\sigma_{\overline{RTT}}$$

    где $$\sigma$$ - среднеквадратичное отклонение среднего значения RTT.

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

    Может возникнуть вопрос, почему при потере пакета CWND делается равным 1, а не CWND-1 или CWND/2? Ведь эффективность канала максимальна при наибольшем, возможном значении CWND. Если произошла потеря пакета из-за переполнения буфера, оптимальное значение CWND может быть выбрано лишь при исчерпывающем знании прогноза состояния виртуального канала. Постольку такая информация обычно недоступна, система переходит в режим освобождения буфера ( CWND=1 ). Ведь если потеря была связана с началом сессии обмена с конкурирующим клиентом, операция CWND=CWND-1 проблему не решит. А потеря пакета вызовет таймаут, и канал будет блокирован минимум на 1 секунду, из-за чего произойдет резкое падение скорости передачи.

    Использование стартового значения CWND>1 может увеличить эффективность виртуального ТСРканала. Стартовое значение CWND = 2*MSS представляется вполне разумным. Понятно, что в критических ситуациях CWND=1 должно быть непременно разрешено. На рис. 2.11 показана эволюция CWND (результат моделирования [2.3]) при двух последовательных медленных стартах (один из них может быть вызван случайной потерей сегмента). Отсюда видно, что случайные потери сильно понижают пропускную способность канала.

    2.2.1.4. TCP Westwood

    Среди множества предлагаемых моделей реализации ТСР можно выделить еще одну - TCPW (TCP Westwood). Эта модель позволяет достичь большей эффективности использования канала. В такой модификации протокола используется новый алгоритм управления окном перегрузки, основанный на оценке потока данных (RE - Rate Estimation) и текущего значения полосы пропускания. На основе этих оценок производится вычисление cwin и ssthresh. Для больших произведений полосы на RTT этот алгоритм может дать лучший результат, чем NewReno.

    if(получено 3 DUPACK)
    	ssthresh = (BE*RTTmin)/seg_size;
    if(cwin > ssthresh)     /* исключение перегрузки */ 
    		cwin=ssthresh;
    endif
    endif
    (рис 2.11) Эволюция cwnd при двух медленных стартах (T. V. Lakshman, Upamanyu Madhow, "The performance of TCP/IP for networks with high bandwidth-delay products and random loss", IEEE/ ACM Trans. Networking, V5, N3, p.336-350, June 1997)

    где seg_size идентифицирует длину ТСРсегмента, а DUPACK - задублированное подтверждение, BE - (bandwidth estimation) оценка полосы. Заметим, что после получения n DUPACK следует повторная пересылка потерянных сегментов, как это делается в стандартном режиме быстрой повторной пересылки ТСР Reno. Окно растет после установления его ширины равной ssthresh согласно правилам алгоритма быстрой повторной пересылки ( cwin=cwin+1 при получении каждого ACK и делается равным ssthresh при получении ACK для новых данных). Следовательно, когда получено n DUPACK, мы достигли предела пропускной способности сети. $$window = BE \times RTT_{min}$$.

    Переход к фазе исключения перегрузки связан с плавным поиском доступного значения полосы пропускания канала. Значение RTTmin равно наименьшему значению, измеренному протоколом ТСР. Заметим, что после установления ssthresh значение ширины окна перегрузки делается равным порогу медленного старта, только если cwin > ssthresh. В протоколе TCPW для оценки BE используются ACK. Для этого регистрируется частота ACK и измеряется объем данных, доставленных в единицу времени. $$b_k=d_k/\Delta t_k; \Delta t_k = t_kt_{k-1}$$, где tk - время прихода k -го ACK отправителю, dk - длина подтвержденного сегмента.

    В случае, когда потеря пакета индицируется истечением времени таймаута, значения cwin и sstresh устанавливаются согласно:

    if(произошел таймаут RTO)
    	cwin=1;
    	ssthresh=(BE*RTTmin/seg_size;
    	if(ssthresh<2) 
    	ssthresh=2;
    endif
    endif

    В случае использования комбинированного алгоритма CRB (Combined RE/BE), где применен более сложный алгоритм оценки загрузки и доступной полосы пропускания, присвоение значений cwin и ssthresh производится согласно следующим соотношениям (вариант потери с индикацией посредством присылки 3 DUPACK ):

    if(получено 3 DUPACK)
    if(cwin/((RE*RTTmin)/seg_size)>0)   /* сеть перегружена */
    ssthresh = (RE*RTTmin)/seg_size;
    else                                                 /* перегрузки нет */
    ssthresh = (BE*RTTmin)/seg_size;
    Endif
    if(cwin> ssthresh)              /* исключение перегрузки */
    cwin = ssthresh;
    endif;
    endif

    В случае, когда потеря пакета индицируется по таймауту, значения cwin и ssthresh вычисляются следующим образом:

    if(произошел таймаут RTO)
    	cwin=1;
    	ssthresh=(BE*RTTmin/seg_size;
    	if(ssthresh<2) 
    	ssthresh=2;
    endif;
    endif

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

    Помимо таймаута, в протоколе TCP предусмотрена еще одна возможность уведомления отправителя о потере сегмента. Получатель, контролируя номера приходящих сегментов и обнаружив потерю, может начать посылать двойные ACK для пакетов, следующих за потерянным сегментом. Приход таких дублированных ACK позволяет разрешить проблему до истечения времени таймаута RTO (смотри описание алгоритма TCP-reno). Понятно, что для последнего сегмента в сообщении этот метод не работает и остается только таймаут. Получение двойного ACK не является надежным сигналом потери пакета. Двойные ACK возникают и при смене маршрута обмена. По этой причине сигналом потери считается получение трех ACK пакетов подряд (сигнал быстрой повторной посылки сегмента - fast retransmit). В этом режиме при потере одиночного пакета (Fast Recovery) CWND устанавливается на три сегмента больше, чем значение ssthresh. После получения сигнала ACK значение CWND становится равным ssthresh с дальнейшим линейным увеличением. Здесь приход очередного ACK увеличивает CWND на (MSS*MSS)/CWND. Область линейного увеличения CWND часто называется режимом исключения перегрузки (congestion avoidance) или AIMD (Additive Increase, Multiple Decrease).

    На пути сегмента может повстречаться перегруженный переключатель (L2), который поддерживает алгоритм "обратного давления". Такой сетевой прибор при переполнении его буферов пошлет отправителю уведомление о перегрузке в виде пакета ICMP(4). В ответ на такой сигнал отправитель должен понизить скорость передачи пакетов в два раза. Следует иметь в виду, что подобное событие слабо коррелированно с процессами ТСРобмена и зависит от условий, складывающихся в независимых соседних каналах. Характер реакции на ICMP(4) определяется конкретными особенностями ТСР-драйвера отправителя (не говоря о том, что причиной переполнения может быть UDP-дейтаграмма).

    Вспомним, что, помимо управления перегрузкой со стороны отправителя, в ТСР предусмотрен механизм управления со стороны получателя. Получатель в отклике АСК посылает значение параметра window, определяющее число сегментов, которое готов принять получатель. Механизм управления скользящим окном особенно важен при работе в сетях с большой величиной RTT (например, в случае спутниковых каналов). При этом размер буфера при заданной полосе пропускания канала B и времени задержке t должен равняться $$B \tau /T$$, где $$\tau$$ - время обслуживания пакета, а $$T = t + \tau$$ Канал можно рассматривать как трубу, которая при работе всегда должна быть заполнена. Емкость этой трубы определяется величиной cwnd. Максимально возможная емкость такой трубы Vt в стационарном режиме равна $$V_t = T/ \tau + B = t/ \tau + B +1$$. При этом буфер будет полностью заполнен и $$Т/ \tau$$ пакетов находится в пути. В алгоритме TCP-Tahoe после потери сегмента ssthresh = Vt/2. Понятно, что когда cwnd становится равным Vt, происходит переполнение буфера и потеря пакета. Задача управления перегрузкой виртуального канала является классической проблемой теории массового обслуживания. Аналитическое рассмотрение проблемы и результаты моделирования можно найти в [2.3].

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

    Поиски решения оптимизации ТСР-каналов можно вести по двум направлениям: модифицировать сам ТСР-протокол, адаптируя его для новых условий и требований, - или изменять сетевую среду, делая ее более дружественной по отношению к ТСР. Любое изменение ТСР-протокола должно обеспечить обратную совместимость, чтобы миллионы "старых" программ могли попрежнему работать в этой среде. А это, в свою очередь, предполагает некоторый диалог при установлении виртуального соединения, который бы позволял выяснить, какими версиями ТСР обладают будущие партнеры. Причем сессии с модернизированным ТСР должны уживаться со старыми на всех уровнях. Совокупность этих соображений удерживала до сих пор Интернет-общественность от радикальных модификаций протокола ТСР.

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

    Другой возможностью является привлечение вместо ТСР протокола T/TCP (TCP for Transactions), который улучшает эксплуатационные характеристики виртуального канала в случае коротких транзакций.

    T/TCP помещает данные запроса и флаг завершения FIN в начальный SYN-сегмент. Это может интерпретироваться как попытка открыть сессию, передать данные и закрыть сессию со стороны отправителя. Если сервер воспринимает такой формат, он откликнется одним пакетом, содержащим SYN-отклик, ACK на полученные данные и закрывающим сессию флагом FIN. Для окончательного завершения сессии клиент должен послать серверу сегмент с флагами ACK и FIN. К сожалению, внедрение T/TCP предполагает модификацию программного обеспечения как сервера, так и клиента. По этой причине протокол T/TCP не получает широкого распространения. Кроме того, он достаточно уязвим с точки зрения безопасности.

    Бесспорные преимущества при потере нескольких сегментов за один период RTT предлагает алгоритм выборочного подтверждения SACK (Selective Acknowledgement). Понятно, что следует избегать повторной пересылки благополучно доставленных пакетов (как это делается, например, в протоколе XTP).

    Дополнительные проблемы возникают при реализации ТСР через спутниковые каналы, где RTT превышает 250 мсек, да и BER оставляет желать лучшего. При таких значениях RTT время преодоления ситуации перегрузки может занимать много циклов RTT и достигать десятка секунд. Короткие ТСР-сессии для таких каналов крайне неэффективны (не успеет система поднять значение CWND до приемлемого размера, а уже все данные переданы). Частично это может компенсироваться за счет реализации большого числа ТСРсессий параллельно.

    Хотя ТСР использует соединение "точка--точка", можно попытаться улучшить рабочие характеристики канала, оптимизируя алгоритм управления очередями. Одним из возможных подходов является алгоритм RED (Random Early Detection). RED позволяет маршрутизатору отбрасывать пакеты, даже когда в очереди еще имеется место.

    Следует помнить, что установка пакета в очередь или его отбрасывание согласно правилам RED/WRED (или FQ) осуществляется на уровне IP-протокола (ведь именно он содержит поле заголовка DSCP или метку потока).

    Алгоритм RED использует взвешенное значение длины очереди в качестве фактора, определяющего вероятность отбрасывания пакета. По мере роста средней длины очереди растет вероятность отбрасывания пакетов. Если средняя длина очереди меньше определенного порога, вероятность отбрасывания пакета равна нулю (см. рис. 2.12). Небольшие кластеры пакетов могут успешно пройти через фильтр RED. Более крупные кластеры могут понести потери. Это приводит к тому, что ТСР-сессии с большими открытыми окнами имеют большую вероятность отбрасывания пакетов.

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

    Интересное предложение относительно выборочного (приоритетного) отбрасывания пакетов содержится в работе [2.36] в отношении мультимедиа-потоков.

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

    RED пытается увеличить число коротких перегрузок и избежать долгих.

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

    Существует модификация алгоритма обработки очередей WRED (Weighted Random Early Detection), широко используемая в маршрутизаторах. Этот алгоритм применяется и при реализации DiffServ и гарантированной переадресации (AF), когда решение об обработке пакета принимается в каждом транзитном узле независимо (PHB). При этом может учитываться код DSCP IP-заголовка.

    Алгоритм WRED удобен для адаптивного трафика, который формируется протоколом ТСР, так как здесь потеря пакетов приводит к снижению темпа их передачи отправителем. Алгоритм WRED присваивает пакетам не IP типа нулевой приоритет, повышая вероятность потери таких пакетов. Имеется возможность конфигурации DWRED и DWFQ для одного и того же интерфейса.

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

    (рис 2.12)

    WRED статистически отбрасывает больше пакетов для сессий с большими потоками. По этой причине ТСР-отправители больших потоков будут вынуждены в большей степени понизить поток, чем отправители малого трафика.

    Ни АТМ-интерфейсы маршрутизаторов, ни АТМ-коммутаторы не предоставляют гарантий QoS для UBR виртуальных каналов. Маршрутизатор CISCO может специфицировать только пиковую скорость передачи (PCR) для UBR-канала.

    Маршрутизатор автоматически определяет параметры, которые нужно использовать в вычислениях WRED. Среднее значение длины очереди определяется на основе предыдущего значения и текущего размера очереди, согласно формуле:

    Средняя длина очереди = (old_evarage $$\times$$ (1-2-n)) + (current_{queuesize} $$\times$$ 2-n),

    где n - экспоненциальный весовой фактор, конфигурируемый пользователем. В некоторых статьях о WRED значение 2n обозначается qw.

    Большое значение n сглаживает пики и провалы длины очереди. Средняя длина очереди не будет меняться быстро. Процесс WRED не сразу начнет отбрасывать пакеты при перегрузке, зато продолжит отбрасывание, даже когда перегрузки уже нет (очередь уже сократилась ниже минимального порога). Когда n становится слишком большим, WRED не будет реагировать на перегрузку. Пакеты будут посылаться или отбрасываться так, как если бы WRED не работал.

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

    Вероятность отбрасывания пакета зависит от минимального порога, максимального порога и маркерного деноминатора вероятности. Когда средняя длина очереди выше T1 (Min1, Min2 на рис. 2.12), RED начинает отбрасывать пакеты. Частота отбрасываний увеличивается линейно по мере роста длины очереди до тех пор, пока усредненный размер очереди не достигнет T2 (Max1 и Max2).

    Маркерный деноминатор вероятности pc равен доле теряемых пакетов, когда средняя длина очереди равна T2. Например, если pc равен 1/512, один из 512 пакетов отбрасывается, когда средняя длина очереди достигает T2 (см. рис. 2.13 ниже). Когда длина очереди превышает T2, отбрасываются все пакеты. Минимальный порог T1 следует выбрать достаточно высоким, чтобы максимизировать использование канала.

    Разница между T2 и T1 должна быть достаточно велика, чтобы избежать глобальной синхронизации ТСР агентов (синхронное изменение CWND).

    (рис 2.13)

    В качестве альтернативы можно рассмотреть ситуацию, когда маршрутизатор осуществляет пометку пакетов с помощью битафлага СЕ (Congestion Experienced). Отправитель должен реагировать на этот флаг так, как если бы произошла потеря пакета. Этот механизм, называемый ECN (Explicit Congestion Notification), использует двухбитную схему оповещения, занимая биты 6 и 7 в поле ToS заголовка IPv4 (или два неиспользуемые бита в поле IP Differentiated Services). Бит 6 устанавливается отправителем с целью индикации того, что эта система совместима с ECN (бит ECN ). Бит 7 является СЕ-битом и устанавливается маршрутизатором, когда размер очереди превышает заданное при конфигурации значение. ECN-алгоритм реализует в маршрутизаторе RED. Когда какой-то пакет выбран, он помечается битом СЕ, если в нем установлен бит ECN, - в противном случае пакет отбрасывается.

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

    Исходный диалог установления соединения ТСР при реализации данного алгоритма предполагает добавление возможности ECN-эха и CWR (Congestion Window Reduced) для уведомления партнера о возможности работы с СЕ-битом. Отправитель устанавливает бит ECN во всех посылаемых пакетах. Если отправитель получит ТСР-сегмент с флагом ECN-эхо, он должен подстроить ширину CWND в соответствии с алгоритмом быстрого восстановления при потере одиночного пакета. Следующий посланный пакет должен иметь CWRфлаг, оповещающий получателя о его реакции на перегрузку. Отправитель реагирует подобным образом, по крайней мере, один раз за время RTT. Далее ТСР-пакеты с установленным флагом ECN не вызывают никакой реакции в пределах интервала RTT. Получатель устанавливает ECN-флаг во всех пакетах, когда он получает пакет с установленным битом СЕ. Это продолжается до тех пор, пока он не получит пакет с флагом CWR, указывающим на реакцию отправителя на перегрузку. ECN-флаг устанавливается только в пакетах, которые содержат поле данных. Пакеты ТСР ACK, которые не имеют поля данных, должны содержать флаг ECN=0.

    Соединение не должно ждать получения трех ACK, чтобы детектировать перегрузку. Вместо этого получатель уведомляется о зарождающейся ситуации перегрузки путем установления соответствующего бита, который в свою очередь вызывает соответствующий отклик. Широкое использование ECN в ближайшее время не ожидается, во всяком случае, в контексте IPv4. По этой причине не принято никакого стандарта для позиционирования соответствующих бит в IP-заголовке.

    ECN предоставляет некоторое улучшение эксплуатационных характеристик канала по сравнению со схемой RED, в частности, для коротких ТСР-транзакций. Главной особенностью алгоритма ECN является необходимость изменения программ работы, как маршрутизатора, так и стека TCP/IP. Выгоды этого алгоритма могут стать заметными лишь при достаточно широком внедрении. Можно ожидать более быстрого по отношению ECN распространения алгоритма RED, так как он требует лишь локальной модификации программного обеспечения маршрутизатора.

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

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

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

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

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

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

    Если потеря из-за перегрузки происходит на ранней фазе медленного старта, в сети недостаточно пакетов, чтобы сгенерировать три дублированных ACKотклика для запуска быстрой повторной пересылки и быстрого восстановления. Вместо этого отправитель должен подождать таймаута RTO (минимальное время равно одной секунде). Для коротких сессий длиной (67) RTT ~ нескольких миллисекунд издержки, связанные с потерей одного пакета, слишком велики. Приблизительно 56% повторных передач осуществляется после таймаута RTO.

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

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

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

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

    Иногда возникают ситуации, когда приложение воспринимает управляющие функции ТСР слишком лимитирующими. Это может происходить, например, при управлении общедоступными коммутирующими телефонными сетями через Интернет. В таком варианте не требуется обеспечение строгой последовательности пакетов (отсутствие перепутывания порядка). Кроме того, ограниченное число TCP-сокетов усложняет поддержку приложений, использующих несколько сетевых интерфейсов, да и сам протокол ТСР уязвим для ряда атак, например, для SYN-шторма. Решение такого типа проблем возможно с привлечением протокола SCTP (Stream Control Transmission Protocol).

    Основное отличие между SCTP и TCP проявляется на фазе инициализации, когда партнеры SCTP обмениваются списком оконечных адресов (IP-адресов и номеров портов), которые ассоциируются с текущей сессией. Стартовая процедура SCTP также отличается от традиционного диалога. Здесь получатель не выделяет никаких ресурсов для соединения, что делает процедуру более устойчивой против атак типа SYN-шторма. Инициатор соединения может, в конце концов, откликнуться, послав COOKIEECHO, куда вкладывается порция данных. Таким образом, информационный обмен начинается уже на фазе формирования виртуального соединения. С этого момента сессия считается открытой.

    Закрытие сессии SCTP также отличается от ТСР. В SCTP закрытие сессии с одной стороны означает опустошение очередей и прекращение посылки данных с другой стороны. Здесь через одну и ту же ассоциацию транспортного уровня может осуществляться несколько обменов. Порядок сообщений в рамках одного обмена неукоснительно соблюдается. Каждый поток имеет однозначную идентификацию. Протокол SCTP поддерживает также доставку вне очереди, когда пакет помечается для немедленной доставки, и тогда он получает приоритет и будет доставлен раньше, чем это предписывалось его порядковым номером. Протокол SCTP требует предварительного выяснения значения MTU. таймер повторных передач, запускаемый при посылке каждого сегмента, предусмотрен в SCTP, как и в TCP. Получатель SCTP использует режим подтверждений SACK, реализуемый для каждого второго полученного сегмента. Если сообщение оказалось в зазоре между SACK, после трех таких откликов отправитель повторно посылает это сообщение и сокращает вдвое CWND.

    Применение обменов точка-мультиточка предполагает, что каждый оконечный адрес, ассоциированный с одной и той же ЭВМ, не обязательно использует один и тот же путь. Поэтому для каждой конечной точки периодически должна производится проверка осуществимости связи (процедура keepalive ).

    Идея совмещения состояния ТСР перегрузки для нескольких каналов применима и для смеси потоков с гарантией и без гарантии доставки, осуществляющих одновременно обмен между общими конечными пунктами. Именно такая схема мультиплексирования реализуется в модели менеджера перегрузки. Менеджер перегрузки представляет собой модуль оконечной системы, который позволяет набору одновременных потоков от ЭВМ к некоторой точке назначения совместно использовать общую систему управления перегрузкой.

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

    Реализация общей функции управления перегрузкой может базироваться на механизме отзыва (callback), когда приложение посылает запрос менеджеру перегрузки (МП). МП откликается посылкой отзыва, и приложение после этого может послать информационный сегмент протокольному драйверу.

    Другой поддерживаемый механизм МП называется синхронной передачей. Здесь МП предоставляет приложению данные о состоянии канала (пропускная способность, RTT и т.д.) и оно может осуществить запрос, лишь когда состояние сети изменится существенным образом (пороги по базовым параметрам задаются при конфигурации). Удаленная ЭВМ информирует МП о числе полученных и потерянных байтов, о результатах измерения RTT, проведенных на уровне приложения. Приложение предоставляет информацию о причинах потерь (истечение таймаута, состояние транзитных сетей или отбрасывание на основе ECN-флагов).

    В последнее время появилось достаточно много версий протокола "лучше чем ТСР", большинство из них предлагаются в комплекте с WEBсервером. Чаще всего это модифицированные версии ТСР - например, за счет таймера более высокого разрешения, позволяющего реагировать более быстро на изменения в сети. Некоторые версии предлагают большее стартовое значение CWND или более быструю версию медленного старта, где размер окна не удваивается, а утраивается на каждом из шагов (за RTT ). Сходные модификации могут быть использованы на фазе избежания перегрузки (линейный участок увеличения CWND ). Все эти модификации вынуждают отправителя вести себя более агрессивно, увеличивая давления на сетевые буферы. Возможно создание программ обмена, где, например, при копировании через сеть файла формируется не одно, а несколько виртуальных соединений. Такого рода решения дают выигрыш главным образом за счет ухудшения условий реализаций других одновременных сессий. Это противоречит общей философии Интернет (Интернет - это клуб джентльменов). Но на самом деле агрессивное поведение ТСР приложения в конечном итоге делает его неэффективным (менее эффективным, чем стандартный ТСР). Как правило, такие решения приводят к большим потерям пакетов, так как их усилия максимально загрузить ресурсы сети заканчиваются понижением чувствительности к сигналам перегрузки. Если же таких приложений в Интернет станет много, это приведет к серьезной деградации пропускной способности каналов из-за перегрузки. Приемлемыми усовершенствованиями ТСР можно признать только такие, которые не ухудшают условий работы для окружающих. Это наилучшая стратегия, так как позволяет использовать ресурсы сети более эффективно для всех участников.

    Работа протокола TCP AIMD в режиме исключения перегрузок можно характеризовать формулой [2.1]:

    $$BW= \frac{MSS} {(RTT \times \sqrt{(1.33 \times p)}) + (RTO \times p \times [1+32 \times p^2] \times \min (1,3 \times \sqrt{0.75 \times p)})}$$

    где BW - полоса пропускания;

    MSS - максимальный размер сегмента в байтах, используемый сессией;

    RTO - таймаут повторной пересылки;

    p - частота потери пакетов (0.01 означает 1% потерь)

    Эта формула является наилучшей аппроксимацией. Некоторое упрощение формулы можно получить, считая RTO=5*RTT.

    Еще более упрощенная формула может быть взята из работы [2.31].

    $$BW= 0.93 \times \frac{MSS}{RTT \sqrt{p}}$$

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

  • Окно получателя не ограничивает рабочих характеристик соединения.
  • Обе формулы позволяют полосе достигать бесконечности при нулевых потерях.
  • Значение RTT является средним и включает в себя задержку, сопряженную с пребыванием пакета в очереди.
  • Формулы работают только для одного ТСР-соединения. Если через канал осуществляется несколько ТСРсоединений, каждое из них следует указанным формулам.
  • Формулы предполагают долговременные ТСР-соединения. Для особо коротких соединений ( <10 пакетов ), когда нет потерь, работает алгоритм медленного старта. Для сессий промежуточной длительности, где в среднем теряется несколько сегментов, параметры окажутся несколько лучше, чем предсказывают формулы.
  • Различие между простой и сложной формулами заключается в том, что сложная формула учитывает влияние таймаутов повторных передач. Для низкого уровня потерь ( <1% ), таймауты обычно не происходят и формулы дают практически идентичные результаты. При высоких потерях ( $$\ge 1%$$ сложная формула дает большую точность оценки.
  • Выводы

  • TCP уязвимость в отношении случайных потерь делает трудным мультиплексирование информационного потока с трафиком реального времени при заметных временных вариациях скорости передачи (например, мультимедиа), в особенности, если оба вида трафика работают с общим буфером, что типично для большинства современных сетей. В сетях ATM, однако, TCP соединения могут поддерживаться с помощью классов трафика UBR или ABR, которые обычно буферизуются отдельно от высоко приоритетного VBR (Variable Bit Rate) или CBR (Constant Bit Rate) трафика. Если последние классы трафика имеют более высокий приоритет, TCP соединения обнаружат для себя емкость канала, варьируемую со временем, оставшуюся после обслуживания потоков VBR и CBR. Эти вариации могут приводить к "случайным потерям", которые сильно ухудшают рабочие характеристики. Однако если буфер имеет достаточный объем, чтобы сгладить эти вариации и удержать вероятность потери для соединения "точка--точка" ниже обратного квадрата произведения полосы на задержку, то рабочие характеристики TCP не будут серьезно ухудшены. Включение селективного подтверждения в TCP облегчит эту проблему, так как размер окна не нужно резко сокращать для изолированных случайных потерь.
  • В дополнение к уязвимости от случайных потерь, тот факт, что потери являются основным средством обратной связи, используемым TCP, приводит к непомерным задержкам. Это происходит потому, что в сетях с высоким коэффициентом использования размер окна для TCP соединения будет увеличиваться и, после того как возможности узкого участка канала окажутся полностью исчерпанными, а буфер переполненным, произойдет потеря. Задержка и рабочие характеристики при потерях могут быть существенно улучшены, если мы вместо этого используем схему, которая лишь пытается поддерживать ширину окна, чтобы достичь высокого использования канала. Такая схема, как DECbit [2.26], реализует это, используя явную обратную связь со стороны коммутаторов; подобные схемы имеет смысл рассмотреть, особенно потому, что Explicit Congestion Notification (явное оповещение о перегрузке) встроена в качестве опции для сетей ATM. Заметим, однако, что схема DECbit, в частности, подвержена, как и TCP, проблемам при работе с соединениями при больших задержках распространения. Другой возможностью является более изощренная оценка RTT, сходная с тем, что сделано в работе [2.22]. Это, конечно, привлекательно, так как исключает необходимость явной обратной связи. Однако если задержка RTT может меняться существенно без изменения загрузки в канале (например, из-за того, что задержка обработки в узлах зависит от загрузки операционной системы или потому, что задержки связаны с особенностями работы мобильных приложений), тогда адаптация, базирующаяся на обработке задержек, может оказаться менее устойчивой, чем адаптация на основе потерь или явной обратной связи. Кроме того, если различные соединения не изолированы друг от друга с точки зрения использования ими полосы и сетевых буферов, тогда соединение, которое более агрессивно в отношении получения полосы и поднимающее скорость передачи до тех пор, пока не произойдет потеря, забьет соединения, которые анализируют RTT, чтобы избежать перегрузки. Таким образом, изменения на транспортном уровне должны либо адаптироваться универсально, либо тесно сотрудничать с сетевым уровнем, отслеживающим "алчные" соединения.
  • Использование групповых подтверждений в TCP мотивирует в TCPtahoe сокращение ширины окна до единицы после потери, чтобы избежать всплеска потока пакетов из-за повторной их передачи. Это, в свою очередь, приводит к экспоненциальному увеличению размера окна при медленном старте, необходимому для сетей с большим произведением полосы на задержку. С другой стороны, это экспоненциальное увеличение вызывает серьезные флуктуации трафика, которые, если размер буфера меньше, чем 1/3 от произведения полосы на задержку, вызывает переполнение буфера и второй медленный старт, понижая пропускную способность. TCP-reno пытается избежать этого явления путем сокращения окна вдвое при обнаружении потери. В то время как это при идеальных условиях обеспечивает улучшенную пропускную способность, TCP-reno в его нынешнем виде слишком уязвим для фазовых эффектов и множественной потери пакетов, чтобы стать заменителем для TCP-tahoe. Основной проблемой с TCP-reno является то, что могут быть множественные ограничения на окно, связанные с одним эпизодом перегрузки, и что множественные потери могут приводить к таймауту (который на практике вызывает значительное снижение пропускной способности, если используются таймеры с низким разрешением). Версия TCP-Vegas [2.4,9] пытается реализовать ряд усовершенствований, таких, как более изощренная обработка и оценка RTT. Но для флуктуаций RTT в Интернет существует много других причин помимо заполнения буфера. Для того, чтобы существенно улучшить существующие версии TCP, необходимо избегать резких сокращений размеров окна как в TCP-tahoe, так и в TCP-reno за исключением случая, когда имеет место продолжительная перегрузка (которая вызывает массовые потери пакетов). Одним возможным средством обработки изолированных потерь без изменения размера окна является использование некоторой формы селективного подтверждения. В ожидании разработки удовлетворительного нового варианта предлагается применять TCPtahoe (в сочетании с управлением сетевого уровня, чтобы оптимизировать рабочие характеристики), так как этот вариант несравненно устойчивей, чем TCPreno.
  • Несовершенство TCP для соединений с высокими задержками распространения может вызвать проблемы при мультиплексировании потоков на короткие и дальние расстояния в WAN. Короче говоря, эти эксплуатационные проблемы могут не проявиться, так как WAN может быть существенно недогружена и там может не оказаться узких мест (т.e. размер окна, необходимый для хорошей работы, может быть слишком мал, чтобы вызвать переполнение буфера, и поэтому достигается максимальная стационарная пропускная способность). Однако, для гарантирования рабочих характеристик в высоко загруженных сетях, каждое TCP соединение должно иметь зарезервированный буфер и полосу пропускания вдоль всего сетевого маршрута. Обычно выделение ресурсов осуществляется при формировании соединения и заставляет коммутаторы и маршрутизаторы формировать независимые очереди для каждого соединения [2.11], [2.25]. Так как администрирование ресурсов по принципу "наилучшего возможного" может оказаться весьма дорогим, более приемлемой альтернативой может быть резервирование ресурсов для каждого класса трафика. В такой ситуации несовершенство будет сохраняться, если TCP поддерживается поверх ATM с классом трафика UBR. Однако если TCP поддерживается поверх класса трафика ABR, варьирующаяся со временем скорость передачи, доступная для каждого соединения, определяется на сетевом уровне и администрируется отправителем, так, чтобы различные TCP соединения были изолированы друг от друга, даже если они совместно используют буферы.
  • Так как предубеждение против соединений с большими задержками RTT связано с механизмом адаптации окна, оно в принципе может быть преодолено путем модификации механизма мониторирования полосы во время фазы избежания перегрузки, например, путем увеличения размера окна так, чтобы темп увеличения пропускной способности для всех соединений был одним и тем же (такая схема была рассмотрена, но не рекомендована в [2.13]). Однако невозможно выбрать универсальный временной масштаб для настройки окна, который бы работал для сетей с разной пропускной способностью и топологией. Во-первых, зондирование дополнительной полосы с темпом 1 Mбит/с в секунду может быть слишком быстрым для сети с каналом 1 Mбит/с, но слишком медленным для гигабитной сети. Таким образом, чтобы заставить работать такую схему, некоторый обмен между сетевым и транспортным уровнем был бы крайне существенным. Во-вторых, такая схема будет все же подвержена сильному воздействию некоторых недостатков TCP, таких, как деградация рабочих характеристик при наличии случайных потерь и чрезмерных задержек, связанных с попытками использования дополнительной полосы в условиях полного использования канала. Таким образом, эта модификация не может считаться лучшим подходом к проблеме оптимальности.
  • Суммируя, можно сказать, что мы идентифицировали несколько недостатков TCP, мы также представили возможные средства получения хороших рабочих характеристик посредством решений сетевого уровня, таких, как изоляция соединений друг от друга и предоставление буферов достаточного объема, чтобы устранить быстрые вариации доступной канальной емкости. Но нужно помнить, что нельзя увеличивать объем буфера беспредельно, так как это может привести к таймаутам и, в конечном итоге, к большим потерям пропускной способности. Особенно интересным является вопрос, как наилучшим образом поддержать TCP поверх ATM классов услуг ABR и UBR, так как это включает адаптацию сетевого и транспортного уровней. Другой важной областью исследований является разработка альтернативного механизма управления окном, который устранит некоторые недостатки TCP, сохранив его децентрализованную структуру. Децентрализованное адаптивное управление скоростью передачи, при сохранении справедливости распределения ресурсов, - задача трудная, если вообще возможная, но некоторое улучшение TCP несомненно реально. Возможные усовершенствования могут превзойти алгоритм исключения перегрузки за счет более изощренной оценки задержек RTT и использования селективного подтверждения, чтобы улучшить рабочие характеристики при наличии случайных потерь.

    Здесь уместно сказать, что радикальным решением могло бы быть исчерпывающее информирование отправителя о состоянии и динамике заполнения всех буферов вдоль виртуального соединения. Такой алгоритм можно реализовать лишь при условии, что все сетевое оборудование вдоль виртуального пути способно распознавать сегменты отклики и выдавать требующиеся данные в рамках определенного протокола (в том числе и оборудование уровня L2!). Здесь предполагается, что маршрут движения сегментов туда и обратно идентичны. В последнее время появилось оборудование L2 (Ethernet), способное фильтровать трафик по IP-адресам и даже номерам портов (а это уже уровень L4). Так что решение уже не представляется чем-то совершенно фантастическим. Такие сетевые приборы могли бы помещать в пакеты откликов ACK информацию о состоянии своих буферов. Учитывая, что объемы буферов в разных устройствах могут отличаться весьма сильно, имеет смысл выдавать не число занятых позиций, а относительную долю занятого буферного пространства. Проблема здесь в том, что длительное время даже в локальных сетях, я уже не говорю про Интернет, будут сосуществовать сетевые устройства, как поддерживающие этот новый протокол, так и старые - не поддерживающие. Но даже в таких условиях этот протокол будет давать заметный выигрыш. Ведь новые устройства будут ставиться в первую очередь именно в "узких" местах сети, где потери были наиболее значимы. Условия загрузки нового устройства останутся теми же, но о них отправитель получит исчерпывающую информацию и за счет этого сможет оптимизировать трафик. При этом отправитель должен отслеживать не просто состояние на текущий момент, но и темп заполнения и освобождения буферов. Ширина окна в таком случае может определяться на основе прогноза состояния буфера на момент, когда туда придет соответствующий ТСРсегмент. Для этого отправителю придется выделить дополнительную память для хранения уровней заполнения буферов. Задержка в цепи отслеживания состояния тракта при этом будет минимальной. Существенный выигрыш могут получить сервис провайдеры с однородной структурой оборудования.

    Проблема усложнена разнообразием технологий L2, ведь трудно себе представить, что нужную информацию о состоянии буферов будет выдавать ATM или SDH. Но наметившаяся тенденция использования Ethernet не только в LAN, но и в региональных сетях, может упростить задачу.

    Альтернативой этому алгоритму могла бы служить схема, где каждому виртуальному соединению в каждом вовлеченном сетевом устройстве (включая L2) выделяется свой независимый буфер известного объема.

    Любое из названных решений требует замены огромного объема оборудования. Но, вопервых, раз в 25 лет оборудование все равно обновляется, вовторых, это даст выигрыш в пропускной способности не менее двух раз и существенно упростит задачу обеспечения требуемого уровня QoS.

    Первым шагом на пути внедрения отслеживания уровня заполнения буфера может служить ECN-алгоритм, описанный выше.

    Разрабатывая новые версии драйверов ТСР-протокола, надо с самого начала думать и о сетевой безопасности, устойчивости программ против активных атак.

    Новые трудности в реализации модели протокола ТСР возникли при работе с современными быстрыми (110 Гбит/с) и длинными ( RTT>200мсек ) каналами. Для пакетов с длиной 1500 байт время формирования окна оптимального размера достигает 83333 RTT (режим предотвращения перегрузки), что при RTT=100 мсек составляет 1,5 часа! При этом требования к вероятности потери пакетов становятся невыполнимыми. В норме для таких каналов BER лежит в пределах 10-7 - 10-8. Разрешение проблемы возможно путем использования опции Jumbo пакетов или за счет открытия нескольких параллельных ТСРсоединений. В последнее время предложено несколько новых моделей реализации ТСР: High Speed TCP (HSTCP - S.Floyd), Scalable TCP (STCP - T.Kelly), FAST (http://datatag.web.cern.ch/datatag/pfldnet2003/papers/ low.pdf), XCP (http://portal.acm.org/citation.cfm?doid=633035), SABUL (Y.Gu, X.Hong). Модификации HSTCP и STCP характеризуются тем, что при нескольких потоках с разными RTT они некорректно распределяют полосу. В этих условиях заметные трудности создает синхронизация потерь для конкурирующих потоков. Специально для случая высокой скорости и больших задержек разработана модификация BI-TCP (Binary Increase TCP - http://www.csc.ncsu.edu/faculty/rhee/export/bitcp.pdf, Lisong Xu, Khaled Harfoush and Injong Rhee, Binary Increase Congestion Control for Fast, Long Distance Networks). Протокол BI-TCP имеет следующие свойства:

  • Масштабируемость. Протокол может масштабировать свою долю полосы до 10 Гбит/c при BER ~ 3,5?108 .
  • RTT (равенство условий). При больших значениях окна его RTT неэквивалентность (unfairness) пропорциональна RTT-отношению (как в случае AIMD).
  • TCP дружественность. Протокол достигает ограниченной ТСР-эквивалентности для всех размеров окна. Для высокой вероятности потерь, где ТСР работает хорошо, ТСРдружественность сопоставима с STCP.
  • Эквивалентность (fairness) и сходимость. По сравнению с HSTCP и STCP, он позволяет получить большую эквивалентность полос пропускания в широком временном диапазоне и быструю сходимость к уровням справедливых долей.
  • AIMD демонстрирует квадратичный рост пропускной способности при увеличении отношения RTT (линейный рост "несправедливости"). Для других протоколов степень несправедливости еще выше.

    Функция отклика протокола на перегрузку определяется отношением скоростей передачи пакетов в зависимости от вероятности их потери.

    BI-TCP встраивается в TCPS-ACK. В протоколе используются следующие фиксированные параметры:

    Low_window - если размер окна больше чем этот порог, используется BI-TCP, в противном случае - обычный ТСР;

    Smax - максимальное приращение;

    Smin - минимальное приращение;

    $$\beta$$ - мультипликативный коэффициент сокращений ширины окна;

    default_max_win - значение максимума окна по умолчанию

    В протоколе используются следующие параметры:

    max_win - максимальное значение ширины окна, в начале равно величине по умолчанию;

    min_win - минимальная ширина окна;

    prev_win - максимальное значение ширины окна до установления нового максимума;

    target_win - средняя точка между максимумом и минимумом ширины окна;

    Cwnd - размер окна перегрузки;

    is_BITCP_ss - Булева переменная, указывающая, находится ли протокол в режиме медленного старта. В начале = false ;

    ss_cwnd - переменная, отслеживающая эволюцию cwnd при медленном старте;

    ss_target - значение cwnd после одного RTT при медленном старте BI-TCP.

    При входе в режим быстрого восстановления:

    if (low_window <= cwnd) {
    	prev_max = max_win;
    	max_win = cwnd;
    	cwnd = cwnd *(1?);
    	min_win = cwnd;
    	if (prev_max > max _win) //Fast. Conv.
    	max_win = (max_win + min_win)/2;
    	target_win = (max_win + min_win)/2;
    } else {
    	cwnd = cwnd*0,5; //normal TCP

    Когда система не находится в режиме быстрого восстановления и приходит подтверждение для нового пакета, то:

    if (low_window > cwnd) {
    	cwnd =cwnd + 1/cwnd; // normal TCP
    	return
    }
    if (is_BITCP_ss is false) { //bin.increase
    	if (target_win  cwnd < Smax) // bin.search
    		cwnd += (target_win  cwnd)/cwnd;
    	else
    		cwnd += Smax/cwnd; // additive incre.
    	if (max_win > cwnd) {
    		min_win = cwnd;
    	target_win = (max_win + min_win)/2;
    	} else {
    		is_BITCP_ss = true
    		ss_cwnd =1;
    		ss_target = cwnd+1;
    		max_win = default_max_win;
    	}
    } else {
    	cwnd = cwnd + ss_cwnd/cwnd;
    	if(cwnd >= ss_target) {
    		ss_cwnd = 2*ss_cwnd; ss_target = cwnd + ss_cwnd;
    	}
    		if(ss_cwnd >= Smax)
    		is_BITCP_ss = false;
    }

    2.2.1.5. Характеристики BI-TCP

    При анализе характеристик протокола предполагается, что потери пакетов происходят с вероятностью 1/р. Авторы определяют эпоху перегрузки как время между двумя последовательными потерями пакетов.

    Пусть Wmax обозначает размер окна непосредственно перед потерей пакета. После потери размер окна уменьшается до $$W_{max}(1 - \beta)$$. BI-TCP переключается от аддитивного увеличения к двоичному поисковому увеличению окна, когда различие между текущим значением ширины окна и конечным значением ( target ) меньше Smax. Так как конечное (target) значение ширины окна является средней точкой между Wmax и текущим значением ширины окна, можно сказать, что BI-TCP переключается между этими двумя приращениями, когда разница между текущей шириной окна и Wmax меньше 2Smax. Ниже в таблицах 2.2 и 2.3 представлены расчетные характеристики протоколов AIMD, BITCP, HSTCP и STCP для каналов с быстродействием 100 и 2500 Мбит/c.

    Отношения пропускной способности протоколов при 100Мбит/c
    отношение RTT 1 3 6
    AIMD 0,99 7,31 26,12
    BI-TCP 0,94 13,06 33,81
    HSTCP 1,13 10,42 51,09
    STCP 1,12 27,84 72,74

    На рис. 2.14 приведены расчетные данные для откликов при использовании разных модификаций протокола ТСР.

    Отношения пропускной способности протоколов при 2,5Гбит/c
    отношение RTT 1 3 6
    AIMD 1,05 6,56 22,55
    BI-TCP 0,96 9,18 35,76
    HSTCP 0,99 47,42 131,03
    STCP 0,92 140,52 300,32
    (рис 2.14) Сравнение функций отклика для разных протоколов (http://www.csc.ncsu.edu/faculty/rhee/export/bitcp.pdf)

    Еще более радикальным является предложение нового транспортного протокола, описанное в http://book.itep.ru/4/44/ new_tcp.htm.

    Список документов RFC, посвященных протоколу TCP, начиная с 1997 года

    2018 TCP Selective Acknowledgement Options. M. Mathis, J. Mahdavi, S. Floyd, A. Romanow. October 1996.

    2042 Registering New BGP Attribute Types. B. Manning. January 1997.

    2126 ISO Transport Service on top of TCP (ITOT). Y. Pouffary, A. Young. March 1997.

    2140 TCP Control Block Interdependence. J. Touch. April 1997.

    2309 Recommendations on Queue Management and Congestion Avoidance in the Internet. B. Braden, D. Clark, J. Crowcroft, B. Davie, S. Deering, D. Estrin, S. Floyd, V. Jacobson, G. Minshall, C. Partridge, L. Peterson, K. Ramakrishnan, S. Shenker, J. Wroclawski, L. Zhang. April 1998.

    2398 Some Testing Tools for TCP Implementors. S. Parker, C. Schmechel. August 1998. (Also FYI0033)

    2414 Increasing TCP's Initial Window. M. Allman, S. Floyd, C. Partridge. September 1998.

    2415 Simulation Studies of Increased Initial TCP Window Size. K. Poduri, K. Nichols. September 1998.

    2416 When TCP Starts Up With Four Packets Into Only Three Buffers. T. Shepard, C. Partridge. September 1998.

    2488 Enhancing TCP Over Satellite Channels using Standard Mechanisms. M. Allman, D. Glover, L. Sanchez. January 1999. (Also BCP0028)

    2525 Known TCP Implementation Problems. V. Paxson, M. Allman, S. Dawson, W. Fenner, J. Griner, I. Heavens, K. Lahey, J. Semke, B. Volz. March 1999.

    2581 TCP Congestion Control. M. Allman, V. Paxson, W. Stevens. April 1999.

    2582 The NewReno Modification to TCP's Fast Recovery Algorithm. S. Floyd, T. Henderson. April 1999.

    2675 IPv6 Jumbograms. D. Borman, S. Deering, R. Hinden. August 1999.

    2760 Ongoing TCP Research Related to Satellites. M. Allman, Ed., S. Dawkins, D. Glover, J. Griner, D. Tran, T. Henderson, J. Heidemann, J. Touch, H. Kruse, S. Ostermann, K. Scott, J. Semke. February 2000.

    2760 Ongoing TCP Research Related to Satellites. M. Allman, Ed., S. Dawkins, D. Glover, J. Griner, D. Tran, T. Henderson, J. Heidemann, J. Touch, H. Kruse, S. Ostermann, K. Scott, J. Semke. February 2000.

    2873 TCP Processing of the IPv4 Precedence Field. X. Xiao, A. Hannan, V. Paxson, E. Crabbe. June 2000.

    2883 An Extension to the Selective Acknowledgement (SACK) Option for TCP. S. Floyd, J. Mahdavi, M. Mathis, M. Podolsky. July 2000.

    2923 TCP Problems with Path MTU Discovery. K. Lahey. September 2000.

    2988 Computing TCP's Retransmission Timer. V. Paxson, M. Allman. November 2000.

    3042 Enhancing TCP's Loss Recovery Using Limited Transmit. M. Allman, H. Balakrishnan, S. Floyd. January 2001.

    3081 Mapping the BEEP Core onto TCP. M. Rose. March 2001.

    3168 The Addition of Explicit Congestion Notification (ECN) to IP. K. Ramakrishnan, S. Floyd, D. Black. September 2001.

    3293 General Switch Management Protocol (GSMP) Packet Encapsulations for Asynchronous Transfer Mode (ATM), Ethernet and Transmission Control Protocol (TCP). T. Worster, A. Doria, J. Buerkle. June 2002.

    3390 Increasing TCP's Initial Window. M. Allman, S. Floyd, C. Partridge. October 2002.

    3448 TCP Friendly Rate Control (TFRC): Protocol Specification. M. Handley, S. Floyd, J. Padhye, J. Widmer. January 2003.

    3449 TCP Performance Implications of Network Path Asymmetry. H. Balakrishnan, V. Padmanabhan, G. Fairhurst, M. Sooriyabandara. December 2002.

    3465 TCP Congestion Control with Appropriate Byte Counting (ABC). M. Allman. February 2003

    3481 TCP over Second (2.5G) and Third (3G) Generation Wireless Networks. H. Inamura, Ed., G. Montenegro, Ed., R. Ludwig, A. Gurtov, F. Khafizov. February 2003.

    351 A Conservative Selective Acknowledgment (SACK)based Loss Recovery Algorithm for TCP. E. Blanton, M. Allman, K. Fall, L. Wang. April 2003.

    3522 The Eifel Detection Algorithm for TCP. R. Ludwig, M. Meyer. April 2003.

    3708 Using TCP Duplicate Selective Acknowledgement (DSACKs) and Stream Control Transmission Protocol (SCTP) Duplicate Transmission Sequence Numbers (TSNs) to Detect Spurious Retransmissions. Blanton, E. and M. Allman, February 2004.

    3782 The NewReno Modification to TCP's Fast Recovery Algorithm. Floyd, S., Henderson, T., and A. Gurtov. April 2004.

    Страницы:

    Транспортными здесь называются протоколы Интернет, чьи пакеты вкладываются в IP-дейтаграммы. В этот перечень вошли UDP, все модификации TCP.

    2.1. Протокол UDP

    Протокол UDP (User Datagram Protocol, RFC-768) является одним из основных и старейших, расположенных непосредственно над IP. Он предоставляет прикладным процессам транспортные услуги, немногим отличающиеся от услуг протокола IP. Протокол UDP обеспечивает доставку дейтаграмм, но не требует подтверждения их получения. Он также не требует соединения с удаленным модулем UDP ("бессвязный" протокол). К заголовку IP-пакета UDP добавляет поля порт отправителя и порт получателя, которые обеспечивают мультиплексирование информации между различными прикладными процессами, а также поля длина UDP-дейтаграммы и контрольная сумма, позволяющие поддерживать целостность данных. Таким образом, если на уровне IP для определения места доставки пакета используется адрес, то на уровне UDP - номер порта.

    Примерами сетевых приложений, применяющих UDP, являются NFS (Network File System), TFTP (Trivial File Transfer protocol, RFC-1350), RPC (Remote Procedure Call, RFC-1057) и SNMP (Simple Network Management Protocol, RFC-1157). Малые накладные расходы, связанные с форматом UDP, а также отсутствие необходимости подтверждения получения пакета делают этот протокол наиболее популярным при реализации приложений мультимедиа, но главное его место работы - локальные сети и мультимедиа.

    Хотя протокол UDP не гарантирует доставки, по умолчанию предполагается, что вероятность потери пакета достаточно мала.

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

    Например, сервер SNMP всегда ожидает сообщения, адресованного в порт 161. Если клиент SNMP желает получить услугу, он посылает запрос в UDP-порт 161 на машину, где работает сервер. На каждой машине может быть только один агент SNMP, т.к. существует только один порт 161. Данный номер порта является общеизвестным, т.е. фиксированным номером, официально выделенным в сети Internet для услуг SNMP.

    Таблицы для стандартных значений номеров портов можно найти по адресу: http://book.itep.ru/4/44/udp_442.htm.

    Данные, отправляемые прикладным процессом через модуль UDP, достигают места назначения как единое целое. Например, если процесс--отправитель производит 5 записей в порт, то процесс--получатель должен будет сделать 5 чтений. Размер каждого записанного сообщения будет совпадать с размером каждого прочитанного. Протокол UDP сохраняет границы сообщений, определяемые прикладным процессом. Он никогда не объединяет несколько сообщений в одно и не делит одно сообщение на части. Формат UDP-сообщений представлен ниже на рис. 2.1:

    (рис 2.1) Формат UDP-дейтаграмм

    Длина сообщения равна числу байт в UDP-дейтаграмме, включая заголовок. Поле UDP контрольная сумма содержит код, полученный в результате контрольного суммирования UDP-заголовка и поля данные. Нетрудно видеть, что этот протокол использует заголовок минимального размера (8 байт). Номера портов от 0 до 1024 стандартизованы. Они предназначены для серверов и использовать их в прикладных задачах не рекомендуется. С номерами портов >1024 могут работать клиенты, но и здесь нужно проявлять осторожность, так как некоторые номера портов заняты стандартными сервисами, поэтому, прежде чем использовать какой--то порт в своей программе, следует заглянуть в соответствующую базу данных IANA (http://www.iana.org/).

    Модуль IP передает поступающий IP-пакет модулю UDP, если в заголовке этого пакета указан код протокола UDP. Когда модуль UDP получает дейтаграмму от модуля IP, он проверяет контрольную сумму, содержащуюся в ее заголовке. Если контрольная сумма равна нулю, это означает, что отправитель ее не подсчитал. ICMP, IGMP, UDP и TCP протоколы имеют один и тот же алгоритм вычисления контрольной суммы (RFC-1071; по модулю 1). Но вычисление контрольной суммы для UDP имеет некоторые особенности. Во--первых, длина UDP-дейтаграммы может содержать нечетное число байт, в этом случае к ней добавляется нулевой байт, который служит лишь для унификации алгоритма и никуда не пересылается. Во--вторых, при расчете контрольной суммы для UDP и TCP добавляются 12-байтные псевдозаголовки, содержащие IP-адреса отправителя и получателя, код протокола и длину дейтаграммы, которые берутся из IP-дейтаграммы (см. рис. 2.2). Как и в случае IP-дейтаграммы, если вычисленная контрольная сумма равна нулю, в соответствующее поле будет записан код 65535.

    (рис 2.2) Псевдозаголовок, используемый при расчете контрольной суммы

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

    Так как максимальная длина IP-дейтаграммы равна 65535 байтам, максимальная протяженность информационного поля UDP-дейтаграммы составляет 65507 байт. На практике большинство систем работает с UDP-дейтаграммами с длиной 8192 байта или менее (если, например, мы имеем дело с Ethernet, то менее 1500 байт). Детальное описание форматов, полей пакетов и пр. читатель может найти в RFC-768.

    2.2. Протокол TCP

    Протокол TCP (transmission control protocol, RFC-793, 1323, 1644[T/TCP], 2018, 2581, 2582[RENO], 2861, 2873, 2883[SACK], 2923[MTU], 2988[RTO], 3293[GSMP], 3448[TFRC], 3465, 3481) в отличие от UDP осуществляет доставку дейтаграмм, называемых сегментами, в виде байтовых потоков с установлением соединения. Протокол TCP применяется в тех случаях, когда требуется гарантированная доставка сообщений. Он использует контрольные суммы пакетов для проверки их целостности и освобождает прикладные процессы от необходимости таймаутов и повторных передач ради обеспечения надежности. При отслеживании подтверждения доставки в TCP реализуется алгоритм "скользящего" окна. Наиболее типичными прикладными процессами, использующими TCP, являются FTP (file transfer protocol - протокол передачи файлов) и telnet (или SSH для удаленного доступа). Кроме того, TCP используют системы SMTP, HTTP, Xwindow, RCP (remote copy), а также "r"-команды. Внутренняя структура модуля TCP гораздо сложнее структуры UDP. Подобно UDP, прикладные процессы взаимодействуют с модулем TCP через порты. Под байтовыми потоками здесь подразумевается то, что один примитив, например, read или write, может вызвать посылку адресату последовательности сегментов, которые образуют некоторый блок данных (сообщение). Применение портов открывает возможность осуществлять несколько соединений между двумя сетевыми объектами (работать с разными процессами).

    Примером прикладного процесса, использующего TCP, может служить FTP, при этом будет работать стек протоколов ftp/tcp/ip/ethernet. Хотя протоколы UDP и TCP могли бы для сходных задач задействовать разные номера портов, обычно этого не происходит. Модули TCP и UDP выполняют функции мультиплексоров/демультиплексоров между прикладными процессами и IP-модулем. При поступлении пакета в модуль IP он будет передан в TCP или UDP-модуль согласно коду, записанному в поле протокола данного IP-пакета. Формат сегмента (пакета) TCP представлен ниже на рис. 2.3. Если вы хотите глубже разобраться с особенностями работы этого протокола, воспользуйтесь услугами программы tcpdump, которая позволяет отслеживать содержимое отправляемых и приходящих пакетов в ходе реализации сессии.

    Если IP-протокол работает с адресами, то TCP, так же, как и UDP, - с портами. Именно с номеров портов отправителя и получателя начинается заголовок TCP-сегмента. 32-битовое поле код позиции в сообщении определяет порядковый номер первого октета в поле данных пользователя. В приложениях передатчика и приемника этому полю соответствуют 32-разрядные счетчики числа байт, которые при переполнении обнуляются. При значении флага syn=1 в этом поле лежит код ISN (Initial Sequence Number; смотри ниже описание процедуры установления связи), выбираемый для конкретного соединения. Первому байту, передаваемому через созданное соединение, присваивается номер ISN+1. Значение ISN может задаваться случайным образом. Но в UNIX 4.4BSD при загрузке ОС ISN делается равным 1 (это нарушает требования RFC), а далее увеличивается на 640000 каждые полсекунды. Аналогичная инкрементация осуществляется при установлении нового соединения. В RFC рекомендуется увеличивать счетчик ISN на 1 каждые 4 микросекунды.

    32-битовое поле номер октета, который должен прийти следующим, содержит код, который на единицу больше номера последнего успешно доставленного (принятого) байта. Содержимое этого поля интерпретируется получателем сегмента, только если присутствует флаг ACK. Это поле заполняется в заголовках всех сегментов, передаваемых после установления соединения, а флаг AСK=1.

    В ТСР предусмотрен режим полнодуплексной передачи. При этом данные могут передаваться в обоих направлениях независимо. В ходе обмена каждая из сторон должна отслеживать позиционные номера передаваемых и принимаемых байт. Если получен сегмент с некоторым кодом поля номер октета, который должен прийти следующим, это означает, что все октеты с номерами, меньшими указанного в данном поле, доставлены благополучно. Если благополучно доставлены байты с номерами 0-N, а затем получен сегмент с номерами байтов (N+k) - (N+k+m), такой сегмент будет буферизован, но подтверждения его получения не последует. Вместо этого посылается отклик, с кодом номер октета, который должен прийти следующим =(N+1). В случае получения сегмента с неверной контрольной суммой будет послан отклик, идентичный предыдущему. Дублированные отклики позволяют детектировать потерю пакета.

    Поле HLEN определяет длину заголовка сегмента, которая измеряется в 32-разрядных словах. Это поле необходимо, так как в заголовке могут содержаться поля опций переменной длины. Далее следует поле резерв, предназначенное для будущего использования, в настоящее время должно обнуляться. Поле размер окна сообщает, сколько октетов готов принять получатель (флаг ACK=1 ) вслед за байтом, указанным в поле номер октета, который должен прийти следующим. Окно имеет принципиальное значение, оно определяет число сегментов, которые могут быть посланы без получения подтверждения. Значение ширины окна может варьироваться во время сессии. Значение этого поля, равное нулю, также допустимо и указывает, что байты вплоть до указанного в поле номер октета, который должен прийти следующим, получены, но адресат временно не может принимать данные. Разрешение на посылку новой информации может быть дано с помощью посылки сегмента с тем же значением поля номер октета, который должен прийти следующим, но ненулевым значением поля ширины окна. Поле контрольная сумма предназначено для обеспечения целостности сообщения. Контрольное суммирование производится по модулю 1. Перед контрольным суммированием к TCP-сегменту добавляется псевдозаголовок (как и в случае протокола UDP), который включает в себя адреса отправителя и получателя, код протокола и длину сегмента, исключая псевдозаголовок. Поле указатель важной информации представляет собой указатель последнего байта, содержащий информацию, которая требует немедленного реагирования. Поле имеет смысл лишь при флаге URG=1, отмечающем сегмент с первым байтом "важной информации". Значение разрядов в 6-битовом коде флаги описано в таблице 2.1. Если флаг ACK=0, значение поля номер октета, который должен прийти следующим, игнориру ется. Флаг URG=1 устанавливается в случае нажатия пользователем клавиш Del или Ctrl+С.

    Значения битов поля флаги
    обозначение битов (слева на право) поля флаги значение бита, если он равен 1
    URG Флаг важной информации, поле Указатель важной информации имеет смысл, если urg=1
    ACK Номер октета, который должен прийти следующим, правилен
    PSH Этот сегмент требует выполнения операции push. Получатель должен передать эти данные прикладной программе как можно быстрее
    RST Прерывание связи
    SYN Флаг для синхронизации номеров сегментов, используется при установлении связи
    FIN Отправитель закончил посылку байтов
    (рис 2.3) Формат TCP-сегмента

    Поле опции зарезервировано на будущее и в заголовке может отсутствовать, его размер переменен и дополняется до кратного 32-бит с помощью поля заполнитель. Формат поля опции представлен на рис. 2.4. В настоящее время определены опции (поле вид):

    0 Конец списка опций.

    1 Никаких операций. Используется для заполнения поля опции до числа октетов, кратного 4.

    2 Максимальный размер сегмента (MSS).

    В поле вид записывается код опции, поле LEN содержит число октетов в описании опции, включая поля вид и LEN. Определены также опции со значением вид=4,5,6,7. В предложении T/TCP (RFC-1644) описаны опции 11, 12 и 13. Поле данные может иметь переменную длину, верхняя его граница задается значением MSS (Maximum Segment Size). Значение MSS может быть задано при установлении соединения каждой из сторон независимо. Для Ethernet MSS=1452 байта.

    Поле данные в TCP-сегменте может и отсутствовать, характер и формат передаваемой информации задается исключительно прикладной программой, теоретически максимальный размер этого поля составляет в отсутствии опций 65495 байт (на практике, помимо MSS, нужно помнить, например, о значении MTU для Ethernet, которое немногим больше 1500 байт). TCP является протоколом, который ориентируется на согласованную работу ЭВМ и программного обеспечения партнеров, участвующих в обмене информацией. Установление соединения клиент-сервер осуществляется в три этапа.

    (рис 2.4) Формат опций для TCP-сегментов
  • Клиент посылает SYNсегмент с указанием номера порта сервера, который предлагается использовать для организации канала связи (active open).
  • Сервер откликается, посылая свой SYNсегмент, содержащий идентификатор (ISN - Initial Sequence Number). Начальное значение ISN не равно нулю. Процедура называется passive open.
  • Клиент отправляет подтверждение (ACK) получения SYN-сегмента от сервера с идентификатором равным ISN(сервера)+1.
  • Стандартная процедура установления связи представлена на рисунке 2.5 (под словом "стандартная" подразумевается отсутствие каких--либо отклонений от штатного режима, например, одновременного открывание соединения со стороны сервера и клиента). Если же соединение одновременно инициируется клиентом и сервером, в конечном итоге будет создан только один виртуальный канал.

    Префикс S на рисунке указывает на сервер, а С - на клиента. Параметры в скобках обозначают относительные значения ISN. После установления соединения ISN(S) = s_seq_1, а ISN(C) = c_seq_1.

    (рис 2.5) Алгоритм установления связи. В рамках представлены состояния клиента и сервера; (см. также рис. 2.6)

    Каждое соединение должно иметь свой неповторимый код ISN. Для реализации режима соединения прикладная программа на одном конце канала устанавливается в режим пассивного доступа ("passive open"), а операционная система на другом конце ставится в режим активного доступа ("active open"). Протокол TCP предполагает реализацию 11 состояний ( established, closed, listen, syn_sent, syn_received и т.д.; см. также RFC-793), переход между которыми строго регламентирован. Машина состояний для протокола TCP может быть описана диаграммой, представленной на рис. 2.5. Здесь состояние closed является начальной и конечной точкой последовательности переходов. Каждое соединение стартует из состояния closed. Из диаграммы машины состояний видно, что ни одному из состояний не поставлен в соответствие какой--либо таймер. Это означает, что машина состояний TCP может оставаться в любом из состояний сколь угодно долго. Исключение составляет keepalive таймер, но его работа является опционной, а время по умолчанию составляет 2 часа. Это означает, что машина состояния может оставаться 2 часа без движения. В случае, когда две ЭВМ (C и S) попытаются установить связь друг с другом одновременно, реализуется режим simultaneous connection (RFC-793). Обе ЭВМ посылают друг другу сигналы SYN. При получении этого сигнала партнеры посылают отклики SYN+ACK. Обе ЭВМ должны обнаружить, что SYN и SYN+ACK относятся к одному и тому же соединению. Когда C и S обнаружат, что SYN+ACK соответствует посланному ранее SYN, они выключат таймер установления соединения и перейдут непосредственно в состояние syn_recvd (смотри рис. 2.4).

    В состоянии established пакет будет принят сервером, если его ISN лежит в пределах s_ack, s_ack+s_wind ( s_wind - ширина окна для сервера; см. рис. 2.6). Аналогичный диапазон ISN для клиента выглядит как: c_ack, c_ack+c_wind ( c_wind ширина окна для клиента). c_wind и s_wind могут быть не равны. Пакеты, для которых эти условия не выполняются, будут отброшены.

    Рассмотрим пример установления соединения для случая FTP-запроса. Пусть клиент С запускает процесс установления FTP-соединения с сервером S. Обычный порядок установления соединения показан ниже (см. рис. 2.4):

    c > s:syn(isnc)
    s > c:syn(isns), ack(isnc)
    c > s: ack(isns) (Связь установлена)
    c > s: данные

    и/или

    s > c: данные

    ISN - идентификатор пакета, посылаемого клиентом (С) или сервером (S). Клиент, послав SYN серверу S, переходит в состояние syn_sent. При этом запускается таймер установления соединения.

    Как при установлении соединения, так и при его разрыве приходится сталкиваться с проблемой двух армий. Представим себе, что имеются две армии А и Б, причем Б больше по численности чем А. Армия Б разделена на две части, размещенные по разные стороны от армии А. Если две части армии Б одновременно нападут на армию А, победа гарантирована. В то же время нападение на А одной из частей армии Б обрекает ее на поражение. Но как обеспечить одновременность? Здесь предполагается, что радио еще не изобретено и передача сообщений осуществляется вестовыми, которые в нашем случае могут быть перехвачены врагом. Как убедиться, что вестовой дошел? Первое, что приходит в голову, это послать другого вестового с подтверждением. Но он также с некоторой вероятностью может быть перехвачен. А отправитель не будет знать, дошел ли он. Ведь если сообщение перехвачено, отправитель первичного запроса не выдаст команды на начало, так как не уверен, дошло ли его первое сообщение. Возникает вопрос, существует ли алгоритм, который бы гарантировал надежность синхронизации решений путем обмена сообщениями при ненадежной доставке? Повысит ли достоверность увеличение числа обменов между партнерами? Ответом на этот вопрос будет - нет, не существует. В этом читатель, порассуждав логически, может убедиться самостоятельно. Нетрудно видеть, что схожие проблемы возникают в любом протоколе, работающем через установление соединения. Чаще всего эта проблема решается путем таймаутов и повторных попыток (это, слава Богу, не война и все обходится без человеческих жертв).

    Сервер, получив SYN, откликается посылкой другого SYN. Когда С получает SYN от S (но не получает ACK, например, из-за его потери или злого умысла), он предполагает, что имеет место случай одновременного открытия соединения. В результате он посылает syn_ack, отключает таймер установления соединения и переходит в состояние syn_received. Сервер получает syn_ack от C, но не посылает отклика. Тогда С ожидает получения syn_ack в состоянии syn_received. Так как время пребывания в этом состоянии не контролируется таймером, С может остаться в состоянии syn_received вечно. Из--за того, что переходы из состояния в состояние не всегда четко определены, протокол TCP допускает и другие виды атак.

    Хотя TCP-соединение является полнодуплексным, при рассмотрении процесса разрыва связи проще его рассматривать как два полудуплексных канала, каждый из которых ликвидируется независимо. Сначала инициатор разрыва посылает сегмент с флагом FIN, сообщая этим партнеру, что не намерен более что--либо передавать ( FIN посылается, как правило, в результате вызова приложением функции close). Когда получение этого сегмента будет подтверждено ( ACK ), данное направление передачи считается ликвидированным (реализуется полузакрытие соединения). При этом передача информации в противоположном направлении может беспрепятственно продолжаться. Когда партнер закончит посылку данных, он также пошлет сегмент с флагом FIN. По получении отклика ACK виртуальный канал считается окончательно ликвидированным.

    Таким образом, для установления связи требуется обмен тремя сегментами, а для разрыва - четырьмя. Но протокол допускает совмещение первого ACK и второго FIN в одном сегменте, сокращая полное число закрывающих сегментов с четырех до трех.

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

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

    Состояние ESTABLISHED (рис. 2.6) указывает на то, что система находится в состоянии с установленным соединением. Четыре состояния в левом углу помещены в границы затененной зоны и соответствуют активному закрытию. Состояния CLOSE_WAIT и LAST_ACK относятся к пассивному закрытию. Переход из состояния SYN_RCVD в LISTEN возможно, если переход в SYN_RCVD осуществлен из состояния LISTEN, а не из состояния SYN_SENT (одновременное открытие двух соединений, получение RST вместо финального ACK ).

    Состояние TIME_WAIT часто называется ожиданием длительностью 2MSL (Maximum Segment Lifetime). Значение MSL задается конкретной реализацией и определяет предельную величину пребывания сегмента в сети. В RFC-793 рекомендуется задавать MSL равным 2 мин. Но нужно помнить, что ТСРсегмент транспортируется в IP-дейтаграмме, содержащей поле TTL. Когда модуль выполнил активное закрытие и в ответ на FIN послал ACK, соединение должно оставаться в состоянии TIME_WAIT в течение времени, в два раза превышающем MSL. Сокет, используемый данным соединением, не может быть задействован другим соединением в продолжение указанного времени. Все сегменты данного соединения, задержавшиеся в пути, во время TIME_WAIT отбрасываются. Этим гарантируется, что сегменты старого соединения не будут восприняты новым соединением. Такая процедура препятствует перезапуску серверов в течение 14 минут, так как в течение данного времени не могут использоваться стандартные значения номеров портов.

    (рис 2.6) Машина состояний для протокола TCP (W.R. Stivens, TCP/IP Illustrated. V1. Addison-Wesley publishing company. 1993. Имеется обновленная версия книги, переведенная на русский язык: У.Ричард Стивенс, "Протоколы TCP/IP. Практическое руководство", BHV, Санкт-Петербург, 2003)

    Состояние FIN_WAIT_2 сопряжено со случаем, когда одна сторона послала сегмент FIN, а другая сторона подтвердила его получение. Если данное соединение не нужно, можно ждать, когда приложение другой стороны получит код конца файла и пришлет свой флаг FIN. Только после этого система перейдет из состояния FIN_WAIT_2 в состояние TIME_WAIT. Теоретически такое ожидание может быть бесконечным. Другая сторона при этом остается в состоянии CLOSE_WAIT, пока приложение не вызовет функцию close. Для решения проблемы часто вводят дополнительный таймер.

    В ТСР возможна ситуация, когда обе стороны запускают процедуру закрытия одновременно (посылают FIN ), что в протоколе ТСР вполне допустимо. Каждая из сторон при этом переходит из состояния ESTABLISHED в состояние FIN_WAIT_1 (после вызова операции closed ). По получении FIN стороны переходят из состояния FIN_WAIT_1 в состояние CLOSING и посылают ACK. После получения ACK происходит переход в состояние TIME_WAIT.

    Когда оператор, работая в диалоговом режиме, нажимает командную клавишу, сегмент, в который помещается эта управляющая последовательность, помечается флагом PSH (push). Это говорит приемнику, что информация из этого сегмента должна быть передана прикладному процессу как можно скорее, не дожидаясь прихода еще какой--либо информации. Сходную функцию выполняет флаг URG. URG позволяет выделить целый массив данных, так как активизирует указатель последнего байта важной информации. Будет ли реакция на эту "важную" информацию, определяет прикладная программа получателя. URG-режим используется для прерываний при работе с FTP, telnet или rlogin. Если до завершения обработки "важной" информации придет еще один сегмент с флагом URG, значение старого указателя конца "важного" сообщения будет утеряно. Это обстоятельство должно учитываться прикладными процессами. Так, telnet в командных последовательностях всегда помещает префиксный байт с кодом 255.

    В режиме удаленного терминала (telnet/ssh) при нажатии любой клавиши формируется и посылается 41-октетный сегмент (здесь не учитываются издержки Ethernet и возможность наличия опций в IP и TCP), который содержит всего один байт полезной информации. В локальной сети здесь проблем не бывает, но в буферах маршрутизаторов в среде Интернет могут возникнуть заторы. Эффективность работы может быть улучшена с помощью алгоритма Нагля (Nagle, 1984; RFC-896). Нагль предложил при однобайтовом обмене посылать первый байт, а последующие буферизовать до прихода подтверждения получения посланного. После этого посылаются все буферизованные октеты, а запись в буфер вводимых кодов возобновляется. Если оператор вводит символы быстро, а сеть работает медленно, этот алгоритм позволяет заметно снизить загрузку канала. Встречаются, впрочем, случаи, когда алгоритм Нагля желательно отключить, например, при работе в Интернет в режиме Х-терминала, где сигналы перемещения мышки должны пересылаться немедленно, чтобы не ввести в заблуждение пользователя относительно истинного положения маркера.

    Существует еще одна проблема при пересылке данных по каналам TCP, которая называется синдром узкого окна (silly window syndrome; Clark, 1982). Такого рода проблема возникает в том случае, когда данные поступают отправителю крупными блоками, а интерактивное приложение адресата считывает информацию побайтно. Предположим, что в исходный момент времени буфер адресата полон и передающая сторона знает об этом ( window=0 ). Интерактивное приложение считывает очередной октет из TCP-потока, при этом TCP-агент адресата посылает отправителю уведомление, разрешающее ему послать один байт. Этот байт будет послан и снова заполнит до краев буфер получателя, что вызовет отправку ACK со значением window=0. Процесс может продолжаться сколь угодно долго, понижая коэффициент использования канала ниже паровозного уровня.

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

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

    В протоколе TCP "скользящее окно" служит для эффективного использования высокопроизводительных каналов с большими значениями RTT.

    Идея скользящего окна отображена на рис. 2.7. Здесь предполагается, что ширина окна равна 7 ( k=7 ; это число может меняться в очень широких пределах, обычно оно равно нескольким тысячам).

    После прихода отклика на пакет <1> окно смещается вправо на одну позицию. Теперь отправитель может послать и пакет <8>. Если порядок прихода откликов нарушается, сдвиг окна может задержаться. Размер окна в сегментах определяется соотношением:

    window > RTT*B/MSS,
    (рис 2.7) Схема использования скользящего окна

    где B - полоса пропускания канала в бит/с, MSS - максимальный размер сегмента в битах, а размер окна window - в сегментах.

    Для протокола TCP механизм скользящего окна может работать на уровне октетов или сегментов. В первом случае нужно учитывать каждый раз размер поля данных переданного и подтвержденного сегмента. В TCP протоколе используется три указателя (стрелки на рис. 2.7):

    Первый указатель определяет положение левого края окна, отделяя посланный сегмент, получивший подтверждение, от посланного сегмента, получение которого не подтверждено. Второй указатель отмечает правый край окна и указывает на сегмент, который может быть послан до получения очередного подтверждения. Третий указатель помечает границу внутри скользящего окна между уже посланными сегментами и теми, которые еще предстоит послать. Получатель организует аналогичные окна для обеспечения контроля потока данных. Если указатель 3 совпадет с указателем 2, отправитель должен прервать дальнейшее отправление пакетов до получения хотя бы одного подтверждения. Обычно получатель посылает одно подтверждение ( ACK ) на два полученных сегмента.

    Регулирование трафика в TCP подразумевает существование двух независимых процессов: контроль доставки, управляемый получателем с помощью параметра window, и контроль перегрузки, управляемый отправителем с помощью окна перегрузки cwnd (congestion window) и ssthresh (slow start threshold). Первый процесс отслеживает заполнение входного буфера получателя, второй - регистрирует перегрузку канала, а также связанные с этим потери и понижает уровень трафика. В исходный момент времени при установлении соединения cwnd делается равным одному MSS, а ssthreth=65535 байтам. Программа, управляющая пересылкой, никогда не пошлет больше байт, чем это задано cwnd и объявленным получателем значением window. Когда получение очередного блока данных подтверждено, значение cwnd увеличивается. Характер этого увеличения зависит от того, осуществляется ли медленный старт или реализуется режим подавления перегрузки. Если cwnd меньше или равно ssthreth, выполняется медленный старт,в противном случае осуществляется режим подавление перегрузки. В последнем варианте cwndi+1 = cwndi + MSS/8 +(MSS*MSS)/cwnd. Если возникает состояние перегрузки канала значение cwnd снова делается равным одному MSS.

    Окно перегрузки (cwnd) позволяет согласовать полную загрузку виртуального соединения и текущие возможности канала, минимизируя потери пакетов при перегрузке.

    В качестве модуля приращения cwnd используется MSS (а не байт). При получении подтверждения ( ACK ) окно перегрузки увеличивается на один сегмент ("медленный старт", CWNDi+1 = CWNDi + размер_сегмента; последнее слагаемое нужно, если размер окна задан в октетах, в противном случае вместо него следует использовать 1), и теперь отправитель может послать, не дожидаясь ACK, уже два сегмента и т.д.. Ширина окна, в конце концов, может стать настолько большой, что ошибка доставки в пределах окна станет заметной. Тогда будет запущена процедура "медленного старта" или другой алгоритм, который определит новое, уменьшенное значение окна. Окно перегрузки позволяет управлять информационным потоком со стороны отправителя, блокируя возможные перегрузки и потери данных в промежуточных узлах сети. Если переполнения не происходит, CWND становится больше окна, объявленного получателем, и именно последнее будет ограничивать поток данных в канале. Размер окна, объявленный получателем, ограничивается произведением полосы пропускания канала (бит/с) на RTT (время распространения пакета туда и обратно). Максимально допустимый размер окна в TCP равен 65535 байт (задается размером поля заголовка). Конечной целью регулирования трафика является установление соответствия между темпом передачи и возможностями приема. Причиной перегрузки может быть не только ограниченность размера буфера, но и недостаточная пропускная способность какого-то участка канала. С учетом этого обстоятельства каждый отправитель формирует два окна: окно получателя (window) и окно перегрузки (cwnd). Реальное значение ширины скользящего окна равно минимальному из этих величин.

    При инициализации соединения окно перегрузки имеет ширину, равную одному MSS. Отправитель посылает сегмент, и если будет прислано подтверждение получения до истечения времени таймаута, размер окна перегрузки удваивается и посылается два сегмента. При получении подтверждения доставки каждого из сегментов окно перегрузки увеличивается на один сегмент максимальной длины. Таким образом, ширина окна перегрузки последовательно удваивается, пока доставка всех сегментов подтверждается. Рост ширины окна перегрузки при этом имеет экспоненциальный характер. Именно эта процедура и называется медленным стартом (Джекобсон, 1988).

    Как было сказано выше, помимо окон перегрузки и получателя в TCP используется третий параметр - порог (иногда он называется порогом медленного старта ssthresh). При установлении соединения ssthresh=64 Kбайт. В случае возникновения таймаута значение ssthresh делается равным CWND/2, а само значение CWND приравнивается одному MSS (см. рис. 2.8). Далее запускается процедура медленного старта, чтобы выяснить возможности канала. При этом экспоненциальный рост cwnd осуществляется вплоть до значения ssthresh. Когда этот уровень cwnd достигнут, дальнейший рост происходит линейно с приращением на каждом шагу равным MSS (рис. 2.8).

    (рис 2.8) Эволюция ширины окна при медленном старте

    Здесь предполагается, что MSS=1 Кбайт. Началу диаграммы соответствует установка значения ssthresh=16 Kбайт. Данная схема позволяет более точно выбрать значение cwnd. Заметим, что в разных реализациях в качестве единицы измерения для cwnd и ssthresh может использоваться число байт или число сегментов. После таймаута, который на рисунке произошел при передаче c номером 12, значение порога понижается до 12 Кбайт ( =cwnd/2 ). Ширина окна cwnd снова начинает расти от передачи к передаче, начиная с одного сегмента, вплоть до нового значения порога ssthresh=12 Кбайт. Стратегия с экспоненциальным и линейным участками изменения ширины окна перегрузки позволяет несколько приблизить среднее его значение к оптимальному. Для локальных сетей, где значение RTT невелико, а вероятность потери пакета мала, оптимизация задания cwnd не так существенна, как в случае протяженных внешних (например, спутниковых) каналов. Ситуация может поменяться, если в локальной сети имеется участок, где вероятность потери пакетов велика. Таким участком может быть МАСбридж (или переключатель), один из каналов которого подключен к сегменту Fast Ethernet, а другой к обычному Ethernet на 10 Мбит/c. Если такой мост не снабжен системой подавления перегрузки (до сих пор такие приборы не имели подобных систем), то каждый из пакетов будет потерян в среднем 9 раз, прежде чем будет передан (здесь предполагается, что передача идет из сегмента FE). При этом cwnd будет практически все время равно MSS, что крайне неэффективно при передаче по каналам Интернет. Такие потери вызовут определенные ошибки при вычислении среднего значения и дисперсии RTT, а как следствие и величин таймаутов. Применение в таких местах маршрутизаторов или других приборов, способных реагировать на перегрузку посредством ICMP(4), решает эту проблему (беда в том, что многие ТСР агенты не реагируют на ICMP(4)). Алгоритм медленного старта придуман как раз для преодоления подобных проблем, так как он минимизирует потери, сопряженные с переполнением буферов.

    Для взаимного согласования операций в рамках TCP-протокола используется четыре таймера.

  • Таймер повторных передач (retransmission; RTO) контролирует время прихода подтверждений ( ACK ). Таймер запускается в момент посылки сегмента. При получении отклика ACK до истечения времени таймера - он сбрасывается. Если же время таймера истекает до прихода ACK, сегмент посылается адресату повторно, а таймер перезапускается.
  • Таймер запросов (persist timer), контролирующий размер окна даже в случае, когда приемное окно закрыто. При window=0 получатель при изменении ситуации посылает сегмент с ненулевым значением ширины окна, что позволит отправителю возобновить свою работу. Но если этот пакет будет потерян, возникнет тупик, тогда каждая из сторон ждет сигнала от партнера. Именно в этой ситуации и используется таймер запросов. По истечении времени этого таймера отправитель пошлет сегмент адресату. Отклик на этот сегмент будет содержать новое значение ширины окна. Таймер запускается каждый раз, когда получен сегмент с window=0.
  • Таймер контроля работоспособности (keepalive), который регистрирует факты выхода из строя или перезагрузки ЭВМ-партнеров. Время по умолчанию равно 2 часам. Keepalive-таймер не является частью TCP-спецификации. Таймер полезен для выявления состояний сервера halfopen при условии, что клиент отключился (например, пользователь выключил свою персональную ЭВМ, не выполнив LOGOUT ). По истечении времени таймера клиенту посылается сегмент проверки состояния. Если в течение 75 секунд не будет получен отклик, сервер повторяет запрос 10 раз с периодом 75 сек, после чего соединение разрывается. При получении любого сегмента от клиента таймер сбрасывается и запускается вновь.
  • 2MSL-таймер (Maximum Segment Lifetime) контролирует время пребывания канала в состоянии TIME_WAIT. Выдержка таймера по умолчанию равно 2 мин (FIN_WAITтаймер). См. рис. 2.6. и RFC-793. Таймер запускается при выполнении процедуры active close в момент посылки последнего ACK.
  • Важным параметром, определяющим рабочие параметры таймеров, является RTT (время путешествия пакета до адресата и обратно). TCPагент самостоятельно измеряет RTT. Такие измерения производятся периодически, и по их результатам корректируется среднее значение RTT:

    RTTm = a*RTTm + (1-a)*RTTi,

    где RTTi - результат очередного измерения, RTTm - величина, полученная в результате усреднения предыдущих измерений, а - коэффициент сглаживания, обычно равный 0.9. RFC-793 рекомендует устанавливать время таймаута для ретрансмиссии RTO (Retransmission TimeOut) равным RTO=RTTm*b, где b равно 2. От корректного выбора этих параметров зависит эффективная работа каналов. Так, занижение времени ретрансмиссии приводит к неоправданным повторным посылкам сегментов, перегружая каналы связи. Для более точного выбора RTO необходимо знать дисперсию RTT. Несколько более корректную оценку RTO можно получить из следующих соотношений (предложено Джекобсоном в 1988 году, он же позднее предложил целочисленный алгоритм реализации этих вычислений):

    RTTm = RTTm + g(RTTi - RTTm)

    D = D + d(|RTTi - RTTm | - D)

    RTO = RTTm + 4D,

    где D - среднее отклонение RTT от равновесного значения, а коэффициенты g = 0,125, d = 0,25. Чем больше g, тем быстрее растет RTO по отношению к RTT. Это хорошо работает до тех пор, пока не произойдет таймаут и ретрансмиссия. В этом случае, получив ACK, трудно решить, какому сегменту соответствует это подтверждение, первому или второму. На эту проблему впервые обратил внимание Фил Карн. Решением проблемы является приостановка коррекции RTTm при таймауте и ретрансмиссиях. Значение RTO зависит от пропускной способности канала и от специфических задержек, например, в случае спутниковых каналов. В основном RTO лежит в секундном диапазоне (515 сек). Наиболее вероятная причина потери пакетов - это перегрузка канала на участках между отправителем и приемником. Указанием на то, что пакет потерян, может служить таймаут или получение дубликата сегмента ACK. Если произошел таймаут, система переходит в режим "медленного старта" (ширина окна перегрузки делается равной 1 сегменту, а значение порога медленного старта - ssthresh делается равным половине cwnd, при котором это произошло). Дублирование ACK иницирует потерю пакета до наступления таймаута. В этом случае сначала меняется алгоритм приращения величины окна перегрузки cwnd (замедляется темп его роста). После прихода очередного ACK новое значение cwnd вычисляется по формуле:

    cwndi+1 = cwndi + (размер_сегмента*размер_сегмента)/cwndi + размер_сегмента/8

    Если же в этот момент величина окна перегрузки меньше или равна некоторому порогу ( ssthresh - slow start threshold, обычно измеряется в байтах), осуществляется "медленный старт". Следует помнить, что TCP требует посылки немедленного подтверждения (дублированного ACK ) при обнаружении прихода сегментов с нарушением порядка следования. Причиной нарушения порядка следования может быть флуктуация задержки в сети или потеря пакета. Если получено три или более задублированных ACK, что является убедительным указанием на потерю пакета, не дожидаясь таймаута, осуществляется повторная передача. Перехода в режим медленного старта в этом случае не производится, но понижаются значения cwnd и ssthresh (почти вдвое).

    Когда TCP-канал закрывается и за время сессии переслано более 16 полых окон, а адресат достижим не через маршрут по умолчанию, то в таблицу маршрутизации заносится следующая информация: усредненное значение RTT, значение дисперсии RTT и ssthresh.

    Если в ходе TCP-сессии получено сообщение ICMP(4) (переполнение канала - quench), требующее снижения потока данных, то cwdn делается равным одному сегменту, а величина порога медленного старта ssthresh не изменяется. На ICMP-сообщения о недостижимости сети или ЭВМ программы TCP-уровня не реагируют.

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

    Будучи однажды создан, канал TCP может существовать "вечно". Если клиент и сервер пассивны, они не заметят того, например, что какой-то бульдозер оборвал кабель или что спутник связи покоится на дне океана. Чтобы это обнаружить, либо клиент, либо сервер должны попытаться послать какуюто информацию. Чтобы информировать систему об этих и подобных им жизненных неурядицах, предусмотрен таймер контроля работоспособности (keepalive). Многим читателям, возможно, приходилось легкомысленно выключать питание своего персонального компьютера, не позаботившись о корректном logout из процедуры ssh или FTP. Если бы не существовало этого таймера, то, включив ЭВМ, вы бы обнаружили, что "находитесь" в заморском депозитарии, где были вчера. Но таймер контроля работоспособности может и прервать сессию, если какой-то промежуточный маршрутизатор произвел перезагрузку или был вынужден поменять маршрут. Принцип работы таймера работоспособности предельно прост. Если канал пассивен, например, 2 часа, сервер посылает клиенту сегмент-зонд. При этом ЭВМклиент может быть в одном из четырех состояний.

  • Работоспособен и достижим для сервера. Отклик от клиента сбросит таймер работоспособности в ноль (начало отсчета очередных двух часов).
  • Вышел из строя, выключен или перезагружается. Сервер посылает 10 запросов с интервалом 75 сек. Если отклика нет, канал закрывается и со стороны сервера.
  • Перезагрузился. Сервер получит отклик типа RESET, и канал будет закрыт.
  • Работоспособен, но не достижим для сервера. Случай тождественен описанному во втором по порядку пункте.
  • Временная постоянная таймера keepalive является системной переменной единой для всех пользователей ЭВМ или даже локальной сети.

    Расширение пропускной способности и надежности телекоммуникационных каналов делает актуальной совершенствование протоколов. Так как TCP является основным транспортным протоколом, попытки усовершенствовать его предпринимаются, начиная с 1992 года (RFC-1323, Якобсон, Браден и Борман; см. также ссылки в конце главы). Целью этих усовершенствований служит повышение эффективности и пропускной способности канала, а также обеспечение безопасности. При этом рассматриваются следующие возможности:

  • увеличение MTU (максимальный передаваемый блок данных);
  • расширение окна за пределы 65535 байт;
  • исключение "трехсегментного" процесса установления связи и "четырехсегментного" ее прерывания (T/TCP, RFC-1644);
  • совершенствование механизма измерения RTT ;
  • оптимизация отслеживания CWND.
  • Оптимальный выбор MTU позволяет минимизировать или исключить фрагментацию (и последующую сборку) сегментов. Верхняя граница на MTU налагается значением MSS (максимальный размер сегмента). Разумно находить и запоминать оптимальные значения MTU для каждого конкретного маршрута. Так как в современных системах используются динамические протоколы маршрутизации, поиск оптимального MTU рекомендуется повторять каждые 10 мин (RFC-1191).

    Как уже отмечалось, размер TCP-окна определяется произведением полосы канала (в бит/с) на RTT в сек. Современный уровень технологий требует увеличения максимально возможного размера окна в 10100 раз. Протокол же разрешает всего 65535 байт. Появление мощных каналов порождает и другие проблемы - потеря пакетов в них обходится слишком дорого, так как "медленный старт" и другие связанные с этим издержки сильно снижают пропускную способность. В последнее время алгоритм медленного старта заменяется более эффективными алгоритмами.

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

    Существуют и другие, могущие показаться забавными проблемы. Каждый сегмент в TCP-протоколе снабжается 32-битным идентификатором. Время жизни IP-пакета (TTL) определяется по максимуму 255 шагами или 255 секундами в зависимости от того, что раньше наступит. Трудно предсказуемая ситуация может произойти, когда канал ликвидирован, затем создан снова (для той же комбинации IP-адресов и портов), а какой-то пакет из предшествующей сессии, погуляв по Интернет, придет уже во время следующей. Есть ли гарантия, что он будет верно идентифицирован? Одной из мер, упомянутых ранее, можно считать использование ограничения по максимальному времени жизни сегмента (MSL) или TTL, хотя снижение значения TTL не всегда возможно - ведь IP-пакетами пользуется не только TCP-протокол и нужна очень гибкая система задания его величины. Во многих приложениях MSL=30 сек (рекомендуемое значение 2 мин слишком велико). Технический прогресс ставит и некоторые новые проблемы. Высокопроизводительные каналы ( $$\ge 1$$ Гбит/с) уже сегодня могут исчерпать разнообразие идентификационных кодов пакетов за один сеанс связи. Появление же двух пакетов с равными идентификаторами может породить неразрешимые трудности. Для передачи мегабайтного файла по гигабитному каналу требуется около 40 мсек (при этом предполагается, что задержка в канале составляет 32 мсек ( RTT=64 мсек)). Собственно передача этой информации занимает 8 мсек. Из этих цифр видно, что традиционные протоколы, размеры окон и пр. могут свести на нет преимущества скоростного (дорогостоящего) канала. Пропускная способность такого канала определяется уже не его полосой, а задержкой. Понятно также, что необходимо расширить поле размера окна с 16 до 32 бит. Чтобы не изменять формат TCPсегментов, можно сделать код размера окна в программе 32-разрядным, сохранив соответствующее поле в сегменте неизменным. Размер окна в этом случае задается как бы в формате с плавающей запятой. При установлении канала определяется масштабный коэффициент n (порядок) лежащий в интервале 0-14. Передача этого коэффициента (один байт) осуществляется сегментом SYN в поле опций. В результате размер окна оказывается равным 65535*2n. Если один из партнеров послал ненулевой масштабный коэффициент, но не получил такого коэффициента от своего партнера по каналу, то n считается равным нулю. Эта схема позволит сосуществовать старым и новым системам. Выбор n возлагается на TCP-модуль системы.

    Чтобы точнее отслеживать вариации RTT, предлагается помещать временные метки в каждый посылаемый сегмент. Так как в TCP используется одно подтверждение ACK на несколько сегментов, правильнее будет сказать, что RTT измеряется при посылке каждого ACK. Способность и готовность партнеров работать в таком режиме временных меток определяется на фазе установления канала. Более точное вычисление RTT позволяет не только корректно выбрать временные постоянные для таймеров, правильно вычислить задержку TIME_WAIT ( TIME_WAIT=8*RTO ), но и отфильтровать "старые" сегменты. Идеология временных меток применяется и в алгоритме PAWS (Protection Against Wrapped Sequence Numbers) для защиты против перепутывания номеров сегментов.

    Предлагаемое усовершенствование TCP - T/TCP модифицирует алгоритмы выполнения операций. T/TCP вводит новую 32-битную системную переменную: число соединений ( CC ). СС позволяет сократить число пересылаемых сегментов при установлении канала, а также отфильтровывать "старые" сегменты, не принадлежащие данной сессии (установленной связи). Время отклика клиента в рамках указанных алгоритмов сокращается до суммы RTT и времени обработки запроса процессором. Данные пришедшие до SYN-сегмента должны буферизоваться для последующей обработки, а не отбрасываться.

    Как уже отмечалось, максимальная длина сегмента (MSS - Maximum Segment Size) в TCP-обменах величина переменная. Длина сегмента определяет длину кадра, в который он вложен. Для локальных Ethernet-сетей MSS=1460 октетов. Чем длиннее кадр, тем выше пропускная способность сети (меньше накладные расходы на заголовок кадра). С другой стороны, при передаче дейтаграмм по внешним каналам, где MTU не столь велик, большое значение MSS приведет к фрагментации пакетов, которая замедлит обмен, поэтому администратор сети должен взвешивать последствия, задавая значения размера сегментов. Если MSS явно не задан, устанавливается значение по умолчанию (536 байт), что соответствует 576-байтной IP-дейтаграмме. Для нелокальных адресов это, как правило, считалось разумным выбором. Следует, впрочем, заметить, что технология идет вперед и MTU для региональных соединений уже превышает 1500 байт.

    2.2.1 Модели реализации протокола TCP и его перспективы

    Как известно протокол TCP (описание протокола смотри, например, в [2.38]) ориентирован на соединение, он использует для транспортировки IP-дейтаграммы (L3), которые пересылаются посредством протокольных кадров уровня L2. Между двумя партнерами может быть прямое соединение, а может располагаться большое число сетевых приборов уровней L2 и L3 (см. рис. 2.9). Если потоки входящих и выходящих сегментов для заданного сетевого устройства равны, режим стационарен и состояние его буферов не меняется. Но маршрутизаторы и переключатели обычно являются многоканальными устройствами. По этой причине, если даже партнеры ТСР-соединения рассчитаны на идентичную скорость обмена, возможна ситуация, когда некоторое сетевое устройство, вовлеченное в обмен, окажется перегруженным. Ведь всегда могут возникать и исчезать новые сессии информационного или мультимедийного обмена, использующие частично те же сетевые устройства. Протокол ТСР функционирует нормально при выполнении ряда условий.

  • Вероятность ошибки доставки (BER) невелика, и потеря пакета вероятнее всего происходит из-за переполнения буфера. Если потеря пакета из-за его искажения существенна, понижение CWND не поможет, и пакеты будут теряться с той же вероятностью (здесь было бы уместно поискать оптимальное значение MTU ).
  • Время доставки ( RTT ) достаточно стабильно, и для его оценки можно использовать простые линейные аппроксимации. Здесь подразумевается, что в рамках сессии все пакеты следуют одним и тем же путем и смена порядка прихода пакетов, хотя и допускается, но маловероятна. Разрешающая способность внутренних часов отправителя должна быть достаточно высока, в противном случае возникают серьезные потери из-за таймаутов.
  • Сеть имеет фиксированную полосу пропускания и, во всяком случае, не допускает скачкообразных ее вариаций. В противном случае потребовался бы механизм для прогнозирования полосы пропускания, а действующие алгоритмы задания CWND оказались бы не эффективными.
  • Буферы сетевых устройств используют схему первый_вошел-первым_вышел (FIFO). Предполагается, что размер этих буферов соответствует произведению RTT*B ( B - полоса пропускания, RTT - сумма времен транспортировки сегмента от отправителя к получателю и времени движения отклика от получателя к отправителю). Если последнее условие нарушено, пропускная способность неизбежно понизится и будет определяться размером буфера, а не полосой пропускания канала.
  • Длительность TCP-сессии больше нескольких RTT, чтобы оправдать используемую протокольную избыточность. Короткие ТСР-сессии, широко используемые WEB-технологией снижают эффективность обмена. (Именно это обстоятельство вынудило в версиях HTTPv1.1 и выше не разрывать ТСР-соединение после вызова очередной страницы).
  • Чтобы минимизировать влияние избыточности, связанной с заголовком ( 20 байт IP +20 байт ТСР + МАС-заголовок ), используемое поле данных должно иметь большой объем. Для узкополосных каналов, где MTU мало, нарушение данного требования делает канал низкоэффективным. По этой причине выявление допустимого MTU в начале сессии должно приветствоваться.
  • Взаимодействие с другими ТСР-сессиями не должно быть разрушительным, приводящим к резкому снижению эффективности виртуального канала.
  • Конечно, данные условия выполняются отнюдь не всегда, и система не рухнет, если эти условия нарушаются часто. Но эффективность работы соединения окажется не оптимальной. Примером ситуации, когда перечисленные условия нарушаются сразу по нескольким позициям, может служить мобильная IP-связь и работа через спутниковые каналы.

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

    Для прояснения модели работы протокола ТСР рассмотрим простой фрагмент сети, отображенный на рис. 2.9.

    (рис 2.9)

    На данном рисунке ЭВМ С1С3 могут осуществлять обмен друг с другом и с ЭВМ С4С6. Переключатели SW работают на уровне L2 имеют буферы и могут быть причиной потерь, так же, как сами ЭВМ и маршрутизаторы GW1-GW2. Понятно, что объектом перегрузки, помимо названных устройств, может стать любой сетевой объект сети Интернет. Если устройства L3 при переполнении своего буфера могут послать отправителю пакета уведомление ICMP(4), то SW в общем случае могут этого и не делать (например, потому что не умеют). Причиной потери может быть и повреждение пакета на безбрежных просторах Интернет. Особые проблемы могут порождать каналы с большим произведением полосы на RTT [2.3]. В основных версиях протокола ТСР для подавления перегрузки используется механизм окон, который управляется потерей пакетов. В современных сетях передача данных, которая создает стационарный трафик, сосуществует с мультимедиа трафиком, который по своей природе нестабилен, что создает дополнительные проблемы для управления с применением оконных алгоритмов. Кроме того, мультимедийный трафик транспортируется обычно протоколом UDP, не предполагающим подтверждений доставки. Именно дейтаграммы UDP могут вызвать переполнение буфера, и об этом станет известно отправителю позднее, после регистрации потери ТСР сегмента.

    Анализируя различные модели работы протокола ТСР, следует учитывать, что в сети Интернет могут встречаться участки с разными протоколами L2 (Ethernet, ATM, SDH, Frame Relay, PPP и т.д.). Эти технологии имеют разные алгоритмы обработки ситуаций перегрузки (или не имеют их вовсе), а отправитель и получатель, как правило, не имеют данных о том, какие протоколы уровня L2 реализуют виртуальное соединение (L4).

    В настоящее время предложено и опробовано несколько разновидностей протокола TCP.

    2.2.1.1. TCP-reno

    В TCP-reno [17, 1990г; RFC-2581] при нормальной ситуации размер окна меняется циклически. Размер окна увеличивается до тех пор, пока не произойдет потеря сегмента. TCP-reno имеет две фазы изменения размера окна: фаза медленного старта и фаза избежания перегрузки. При получении отправителем подтверждения доставки в момент времени t + tA [сек] текущее значение размера окна перегрузки cwnd(t) преобразуется в cwnd(t + tA) согласно (1):

    $$cwnd(t+t_A)= \begin{cases} \text{фаза медленного старта:}\\ cwnd(t) +1, \text{ } f \text{ } cwnd(t) < ssth(t)\\ \text{фаза исключения перегрузки}\\ cwnd(t) +\frac{1}{cwnd(t)}, \text{ } f \text{ } cwnd(t) \ge ssth(t) \end{cases}$$

    где ssth(t) [пакетов] - значение порога, при котором TCP переходит из фазы медленного старта в фазу исключения перегрузки. Когда в результате таймаута детектируется потеря пакета, значения cwnd(t) и ssth(t) обновляются следующим образом:

    cwnd(t)=1; ssth(t)=(cwnd(t))/2;

    С другой стороны, когда TCP детектирует потерю пакета согласно алгоритму быстрой повторной передачи, cwnd(t) и ssth(t) обновляются иначе:

    ssth(t) = (cwnd(t))/2; cwnd(t)= ssth(t);

    TCP-reno после этого переходит в фазу быстрого восстановления. В этой фазе размер окна увеличивается на один пакет, когда получается дублированное подтверждение. С другой стороны, cwnd(t) делается равным ssth(t), когда приходит недублированный отклик для пакета, посланного повторно. В случае таймаута ssth(t)= (cwnd(t))/2; cwnd=1 (смотри описание алгоритма TCP-Tahoe).

    Результаты моделирования показывают, что каждое соединение обычно теряет около двух пакетов в каждом эпизоде перегрузки. Потери случаются, когда буфер полон и одно соединение увеличивает размер окна на единицу. Когда ячейки из этого нового пакета приходит в буфер, они обычно вызывают потерю ячеек, принадлежащих двум пакетам (конец пакета, пришедшего из другого соединения, и начало следующего). Итак, в среднем следует ожидать потерю трех пакетов на одно столкновение. В нашем примере двух соединений с RTT 40 мсек и 80 мсек, раз буфер полон и произошло столкновение, эпизод перегрузки длится 40 мсек. За время этого периода 80 мсек соединение увеличивает свое окно грубо 50% времени. То есть среднее число потерянных пакетов из-за этого увеличивается в 1.5 раза. Следовательно, всего 4.5 пакетов, или 2.25 пакетов на соединение теряется в среднем на один эпизод перегрузки.

    В настоящее время наиболее популярной является модель NewReno, изложенная в документе RFC-3782 (апрель 2004 года), и использующая алгоритм Fast Retransmit Fast Recovery (быстрая повторная пересылка и быстрое восстановление). В случае, когда доступна опция выборочного подтверждения (SACK), отправитель знает, какие пакеты следует переслать повторно на фазе быстрого восстановления (Fast Recovery). В отсутствие опции SACK нет достаточной информации относительно пакетов, которые нужно послать повторно. При получении трех дублированных подтверждений (DUPACK) отправитель считает пакет потерянным и посылает его повторно. После этого отправитель может получить дополнительные дублированные подтверждения, так как получатель осуществляет подтверждение пакетов, которые находятся в пути, когда отправитель перешел в режим Fast Retransmit. В случае потери нескольких пакетов из одного окна отправитель получает новые данные, когда приходит подтверждение для повторно посланных пакетов. Если потерян один пакет и не было смены порядка пакетов, тогда подтверждение этого пакета будет означать успешную доставку всех предыдущих пакетов до перехода в режим Fast Retransmit. Однако если потеряно несколько пакетов, тогда подтверждение повторно посланного пакета подтверждает доставку некоторых, но не всех пакетов, посланных до перехода в режим быстрой повторной пересылки (Fast Retransmit). Такие подтверждения называются частичными (смотри также http://www.acm.org/sigcomm/sigcomm96/ program.html).

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

    Алгоритм NewReno использует переменную recover (восстановление), исходное значение которой равно исходному порядковому номеру пакета. Рассмотрим узловые этапы реализации алгоритма.

  • Три задублированных ACK.

    Когда отправителю приходят три задублированных ACK, а он не находится в состоянии Fast Recovery, проверяется, перекрывает ли поле Cumulative Acknowledgement больший диапазон, чем задано переменной recover. Если это так, то исполняется операция 1A. В противном случае - 1B.

    1A) Запуск Fast Retransmit.

    Если система находится в этом режиме, ssthresh делается равным значению не большему, чем задано уравнением 1. (Это уравнение 3 из [RFC-2581]).

    ssthresh = max (FlightSize / 2, 2*SMSS)     (1)

    где FlightSize - объем доставляемых данных в сети. Кроме того, переменная recover делается равной наибольшему порядковому номеру переданного пакета, и осуществляется переход к пункту 2.

    1B) Без быстрой повторной передачи.

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

  • Вход в режим быстрой повторной передачи.

    Передается потерянный сегмент и устанавливается cwnd равным ssthresh плюс 3*SMSS. Это искусственно увеличивает окно перегрузки на несколько сегментов (три), которые покинули сеть и буферизованы получателем (SMSS - MSS отправителя).

  • Быстрое восстановление.

    Для каждого нового дублированного ACK, полученного в режиме быстрого восстановления, cwnd увеличивается на SMSS. Это искусственно увеличивает окно перегрузки, чтобы учесть сегмент, который покинул сеть.

  • Быстрое восстановление, продолжение.

    Сегмент передается, если это разрешено новым значением cwnd и значением window, объявленным получателем.

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

    Полное подтверждение.

    Если ACK подтверждает все данные вплоть до позиции, указанной переменной recover, тогда ACK подтверждает получение промежуточных сегментов, начиная с передачи потерянного сегмента и получения тройного дублированного ACK. cwnd устанавливается либо (1) min (ssthresh, FlightSize + SMSS) либо (2) ssthresh, где ssthresh равно значению, установленному на этапе 1; это называется снижением ("сдутием") значения окна. Заметим, что FlightSize ( FlightSize - объем посланных, но еще не подтвержденных данных) на этапе 1 относится к объему данных, не доставленных на этапе 1, когда произошел переход в режим быстрого восстановления, в то время как FlightSize на этапе 5 относится к объему данных, не доставленных на этапе 5, когда произошел выход из режима быстрого восстановления. Если выбрана вторая опция, реализации разрешено принять меры, чтобы избежать возможного всплеска информационного потока, в случае, когда объем недоставленных данных в сети много меньше, чем допускает окно перегрузки. Простым механизмом является ограничение числа информационных пакетов, которые могут быть посланы в ответ на одно подтверждение; это в программе моделирования NS называется "maxburst_".

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

    Если это ACK в действительности не подтверждает доставку всех данных вплоть до позиции, заданной recover включительно, тогда это частичное ACK. В этом случае передается первый неподтвержденный сегмент. Снижается значение окна перегрузки с учетом объема новых данных, подтвержденных с использованием поля группового подтверждения. Если частичное ACK подтверждает как минимум один SMSS данных, тогда к окну перегрузки добавляется SMSS байт. Так же, как на этапе 3, это искусственно увеличивает окно перегрузки, чтобы учесть сегмент, который покинул сеть. Посылается новый сегмент, если это разрешено новым значением cwnd. Это "частичное сокращение окна" пытается гарантировать, что, когда режим быстрого восстановления в конце концов завершится, объем недоставленных данных будет примерно равен ssthresh. Выхода из режима быстрого восстановления не производится (т.e., если позднее придет какой--либо задублированный ACK, выполняются шаги 3 и 4).

    Для первого частичного ACK, который приходит во время реализации быстрого восстановления, сбрасывается таймер повторной передачи.

  • Таймауты повторной передачи.

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

  • Этап 1 специфицирует проверку того, что поле кумулятивного подтверждения покрывает больший диапазон, чем это задано переменной recover. Так как поле подтверждения содержит порядковый номер, который получатель ожидает получить, "ack_number" подтверждения покрывает больший диапазон номеров, чем recover, когда:

    ack_number - 1 > recover;

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

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

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

    Другим вариантом реакции на частичное подтверждение может быть повторная посылка более чем одного пакета и сброс таймера повторной пересылки после повторной передачи. В случае множественных потерь пакетов повторная посылка двух пакетов при получении частичного подтверждения обеспечивает более быстрое восстановление системы. Такой подход требует меньше времени, чем N RTT в случае потери N пакетов. Однако при отсутствии опции SACK медленный старт обеспечивает достаточно быстрое восстановление системы без пересылки лишних пакетов.

    TCP отправитель реагирует на частичные ACK сокращением окна перегрузки на величину, соответствующую объему подтвержденных данных, возвращая назад SMSS байт, если частичное ACK подтверждает, по крайней мере, SMSS байт новых данных, и посылая новый сегмент, если это допускается новым значением cwnd. Таким образом, посылается только один отправленный ранее пакет в ответ на каждое частичное подтверждение, но могут быть посланы и новые пакеты, в зависимости от объема подтвержденной частично доставки. Напротив, в варианте NewReno, описанном в (Fall, K. and S. Floyd, "Simulationbased Comparisons of Tahoe, Reno and SACK TCP", Computer Communication Review, July 1996. URL ftp://ftp.ee.lbl.gov/papers/sacks.ps.Z), в случае частичного подтверждения устанавливается значение окна перегрузки, равное ssthresh. Такой подход является более консервативным, и не пытается точно определить число недоставленных пакетов после получения частичного подтверждения.

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

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

    Алгоритм, описанный в RFC-3782, соответствует варианту Careful алгоритма NewReno TCP из RFC-2582 и исключает проблему множественных повторных пересылок. Этот алгоритм использует переменную recover, значение которой соответствует исходному порядковому номеру посланного пакета. После каждого таймаута повторной передачи, наибольший порядковый номер переданного пакета записывается в переменную recover.

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

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

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

    2.2.1.2. TCP Vegas

    TCP-Vegas [9, 1994г] контролирует размер окна путем мониторирования отправителем RTT для пакетов, посланных ранее. Если обнаруживается увеличение RTT, система узнает, что сеть приближается к перегрузке, и сокращает ширину окна. Если RTT уменьшается, отправитель определит, что сеть преодолела перегрузку, и увеличит размер окна. Следовательно, размер окна в идеальной ситуации будет стремиться к требуемому значению. В частности, на фазе исключения перегрузки размер окна будет равен

    $$cwnd(t+t_A)= \begin{cases} cwnd(t)+1,\text{ }\text{ } f \text{ }\text{ } diff<\frac{\alpha}{base \_rtt}\\ cwnd(t.) \text{ }\text{ } \frac{\alpha}{base \_rtt}\le diff \le \frac{\beta}{base \_rtt}; \text{ }\text{ }diff=\frac{cwnd(t)}{base \_rtt}-\frac{cwnd(t)}{rtt}\\ cwnd(t)-1,\text{ }\text{ } \frac{\beta}{base \_rtt}<diff text{ } \end{cases}$$

    где rtt [сек] - зарегистрированное RTT, base_rtt [сек] - наименьшее встретившееся в данном цикле RTT, а $$\alpha$$ и $$\beta$$ - некоторые константы (смотри также [2.3]). Эта модификация ТСР требует высокого разрешения таймера отправителя.

    2.2.1.3. TCP-Tahoe

    Алгоритм TCP-Tahoe является наиболее старым и широко распространенным [2.16]. Этот алгоритм был сформулирован Джакобсоном в 1988 году, некоторые коррекции были внесены в него позднее.

    Если буфер переполнен, какое-то число сегментов будет потеряно. При этом может быть запущено несколько сценариев. Основной вариант - медленный старт, он запускается в рамках классического алгоритма ТСР-Tahoe при потере сегмента и сопряженном с ним таймаутом ( RTO ) у отправителя, так как отправитель не получит сигнала подтверждения ACK для потерянного сегмента. Медленный старт предполагает установку окна перегрузки ( CWND ) равным 1, а порога медленного старта ( ssthresh ) - равным половине значения CWND, при котором произошел таймаут. Сокращение CWND до единицы происходит потому, что отправитель не имеет никакой информации о состоянии сети. Далее после каждого подтверждения CWNDi+1 = CWNDi+1. Эта формула работает до тех пор, пока CWND не станет равным ssthresh. После этого рост CWND становится линейным (смотри формулу 1). Смысл этого алгоритма заключается в удержании значения CWND в области максимально возможных значений. По существу, эта оптимизация осуществляется с помощью потери пакетов. Если потери пакетов не происходит, значение CWND достигает значения window по умолчанию, задаваемого при конфигурации ТСР-драйвера. На рис. 2.10 показана эволюция CWND при потере пакетов.

    (рис 2.10)

    Значение таймаута вычисляется по формуле:

    $$RTO=\overline{RTT}+4\sigma_{\overline{RTT}}$$

    где $$\sigma$$ - среднеквадратичное отклонение среднего значения RTT.

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

    Может возникнуть вопрос, почему при потере пакета CWND делается равным 1, а не CWND-1 или CWND/2? Ведь эффективность канала максимальна при наибольшем, возможном значении CWND. Если произошла потеря пакета из-за переполнения буфера, оптимальное значение CWND может быть выбрано лишь при исчерпывающем знании прогноза состояния виртуального канала. Постольку такая информация обычно недоступна, система переходит в режим освобождения буфера ( CWND=1 ). Ведь если потеря была связана с началом сессии обмена с конкурирующим клиентом, операция CWND=CWND-1 проблему не решит. А потеря пакета вызовет таймаут, и канал будет блокирован минимум на 1 секунду, из-за чего произойдет резкое падение скорости передачи.

    Использование стартового значения CWND>1 может увеличить эффективность виртуального ТСРканала. Стартовое значение CWND = 2*MSS представляется вполне разумным. Понятно, что в критических ситуациях CWND=1 должно быть непременно разрешено. На рис. 2.11 показана эволюция CWND (результат моделирования [2.3]) при двух последовательных медленных стартах (один из них может быть вызван случайной потерей сегмента). Отсюда видно, что случайные потери сильно понижают пропускную способность канала.

    2.2.1.4. TCP Westwood

    Среди множества предлагаемых моделей реализации ТСР можно выделить еще одну - TCPW (TCP Westwood). Эта модель позволяет достичь большей эффективности использования канала. В такой модификации протокола используется новый алгоритм управления окном перегрузки, основанный на оценке потока данных (RE - Rate Estimation) и текущего значения полосы пропускания. На основе этих оценок производится вычисление cwin и ssthresh. Для больших произведений полосы на RTT этот алгоритм может дать лучший результат, чем NewReno.

    if(получено 3 DUPACK)
    	ssthresh = (BE*RTTmin)/seg_size;
    if(cwin > ssthresh)     /* исключение перегрузки */ 
    		cwin=ssthresh;
    endif
    endif
    (рис 2.11) Эволюция cwnd при двух медленных стартах (T. V. Lakshman, Upamanyu Madhow, "The performance of TCP/IP for networks with high bandwidth-delay products and random loss", IEEE/ ACM Trans. Networking, V5, N3, p.336-350, June 1997)

    где seg_size идентифицирует длину ТСРсегмента, а DUPACK - задублированное подтверждение, BE - (bandwidth estimation) оценка полосы. Заметим, что после получения n DUPACK следует повторная пересылка потерянных сегментов, как это делается в стандартном режиме быстрой повторной пересылки ТСР Reno. Окно растет после установления его ширины равной ssthresh согласно правилам алгоритма быстрой повторной пересылки ( cwin=cwin+1 при получении каждого ACK и делается равным ssthresh при получении ACK для новых данных). Следовательно, когда получено n DUPACK, мы достигли предела пропускной способности сети. $$window = BE \times RTT_{min}$$.

    Переход к фазе исключения перегрузки связан с плавным поиском доступного значения полосы пропускания канала. Значение RTTmin равно наименьшему значению, измеренному протоколом ТСР. Заметим, что после установления ssthresh значение ширины окна перегрузки делается равным порогу медленного старта, только если cwin > ssthresh. В протоколе TCPW для оценки BE используются ACK. Для этого регистрируется частота ACK и измеряется объем данных, доставленных в единицу времени. $$b_k=d_k/\Delta t_k; \Delta t_k = t_kt_{k-1}$$, где tk - время прихода k -го ACK отправителю, dk - длина подтвержденного сегмента.

    В случае, когда потеря пакета индицируется истечением времени таймаута, значения cwin и sstresh устанавливаются согласно:

    if(произошел таймаут RTO)
    	cwin=1;
    	ssthresh=(BE*RTTmin/seg_size;
    	if(ssthresh<2) 
    	ssthresh=2;
    endif
    endif

    В случае использования комбинированного алгоритма CRB (Combined RE/BE), где применен более сложный алгоритм оценки загрузки и доступной полосы пропускания, присвоение значений cwin и ssthresh производится согласно следующим соотношениям (вариант потери с индикацией посредством присылки 3 DUPACK ):

    if(получено 3 DUPACK)
    if(cwin/((RE*RTTmin)/seg_size)>0)   /* сеть перегружена */
    ssthresh = (RE*RTTmin)/seg_size;
    else                                                 /* перегрузки нет */
    ssthresh = (BE*RTTmin)/seg_size;
    Endif
    if(cwin> ssthresh)              /* исключение перегрузки */
    cwin = ssthresh;
    endif;
    endif

    В случае, когда потеря пакета индицируется по таймауту, значения cwin и ssthresh вычисляются следующим образом:

    if(произошел таймаут RTO)
    	cwin=1;
    	ssthresh=(BE*RTTmin/seg_size;
    	if(ssthresh<2) 
    	ssthresh=2;
    endif;
    endif

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

    Помимо таймаута, в протоколе TCP предусмотрена еще одна возможность уведомления отправителя о потере сегмента. Получатель, контролируя номера приходящих сегментов и обнаружив потерю, может начать посылать двойные ACK для пакетов, следующих за потерянным сегментом. Приход таких дублированных ACK позволяет разрешить проблему до истечения времени таймаута RTO (смотри описание алгоритма TCP-reno). Понятно, что для последнего сегмента в сообщении этот метод не работает и остается только таймаут. Получение двойного ACK не является надежным сигналом потери пакета. Двойные ACK возникают и при смене маршрута обмена. По этой причине сигналом потери считается получение трех ACK пакетов подряд (сигнал быстрой повторной посылки сегмента - fast retransmit). В этом режиме при потере одиночного пакета (Fast Recovery) CWND устанавливается на три сегмента больше, чем значение ssthresh. После получения сигнала ACK значение CWND становится равным ssthresh с дальнейшим линейным увеличением. Здесь приход очередного ACK увеличивает CWND на (MSS*MSS)/CWND. Область линейного увеличения CWND часто называется режимом исключения перегрузки (congestion avoidance) или AIMD (Additive Increase, Multiple Decrease).

    На пути сегмента может повстречаться перегруженный переключатель (L2), который поддерживает алгоритм "обратного давления". Такой сетевой прибор при переполнении его буферов пошлет отправителю уведомление о перегрузке в виде пакета ICMP(4). В ответ на такой сигнал отправитель должен понизить скорость передачи пакетов в два раза. Следует иметь в виду, что подобное событие слабо коррелированно с процессами ТСРобмена и зависит от условий, складывающихся в независимых соседних каналах. Характер реакции на ICMP(4) определяется конкретными особенностями ТСР-драйвера отправителя (не говоря о том, что причиной переполнения может быть UDP-дейтаграмма).

    Вспомним, что, помимо управления перегрузкой со стороны отправителя, в ТСР предусмотрен механизм управления со стороны получателя. Получатель в отклике АСК посылает значение параметра window, определяющее число сегментов, которое готов принять получатель. Механизм управления скользящим окном особенно важен при работе в сетях с большой величиной RTT (например, в случае спутниковых каналов). При этом размер буфера при заданной полосе пропускания канала B и времени задержке t должен равняться $$B \tau /T$$, где $$\tau$$ - время обслуживания пакета, а $$T = t + \tau$$ Канал можно рассматривать как трубу, которая при работе всегда должна быть заполнена. Емкость этой трубы определяется величиной cwnd. Максимально возможная емкость такой трубы Vt в стационарном режиме равна $$V_t = T/ \tau + B = t/ \tau + B +1$$. При этом буфер будет полностью заполнен и $$Т/ \tau$$ пакетов находится в пути. В алгоритме TCP-Tahoe после потери сегмента ssthresh = Vt/2. Понятно, что когда cwnd становится равным Vt, происходит переполнение буфера и потеря пакета. Задача управления перегрузкой виртуального канала является классической проблемой теории массового обслуживания. Аналитическое рассмотрение проблемы и результаты моделирования можно найти в [2.3].

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

    Поиски решения оптимизации ТСР-каналов можно вести по двум направлениям: модифицировать сам ТСР-протокол, адаптируя его для новых условий и требований, - или изменять сетевую среду, делая ее более дружественной по отношению к ТСР. Любое изменение ТСР-протокола должно обеспечить обратную совместимость, чтобы миллионы "старых" программ могли попрежнему работать в этой среде. А это, в свою очередь, предполагает некоторый диалог при установлении виртуального соединения, который бы позволял выяснить, какими версиями ТСР обладают будущие партнеры. Причем сессии с модернизированным ТСР должны уживаться со старыми на всех уровнях. Совокупность этих соображений удерживала до сих пор Интернет-общественность от радикальных модификаций протокола ТСР.

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

    Другой возможностью является привлечение вместо ТСР протокола T/TCP (TCP for Transactions), который улучшает эксплуатационные характеристики виртуального канала в случае коротких транзакций.

    T/TCP помещает данные запроса и флаг завершения FIN в начальный SYN-сегмент. Это может интерпретироваться как попытка открыть сессию, передать данные и закрыть сессию со стороны отправителя. Если сервер воспринимает такой формат, он откликнется одним пакетом, содержащим SYN-отклик, ACK на полученные данные и закрывающим сессию флагом FIN. Для окончательного завершения сессии клиент должен послать серверу сегмент с флагами ACK и FIN. К сожалению, внедрение T/TCP предполагает модификацию программного обеспечения как сервера, так и клиента. По этой причине протокол T/TCP не получает широкого распространения. Кроме того, он достаточно уязвим с точки зрения безопасности.

    Бесспорные преимущества при потере нескольких сегментов за один период RTT предлагает алгоритм выборочного подтверждения SACK (Selective Acknowledgement). Понятно, что следует избегать повторной пересылки благополучно доставленных пакетов (как это делается, например, в протоколе XTP).

    Дополнительные проблемы возникают при реализации ТСР через спутниковые каналы, где RTT превышает 250 мсек, да и BER оставляет желать лучшего. При таких значениях RTT время преодоления ситуации перегрузки может занимать много циклов RTT и достигать десятка секунд. Короткие ТСР-сессии для таких каналов крайне неэффективны (не успеет система поднять значение CWND до приемлемого размера, а уже все данные переданы). Частично это может компенсироваться за счет реализации большого числа ТСРсессий параллельно.

    Хотя ТСР использует соединение "точка--точка", можно попытаться улучшить рабочие характеристики канала, оптимизируя алгоритм управления очередями. Одним из возможных подходов является алгоритм RED (Random Early Detection). RED позволяет маршрутизатору отбрасывать пакеты, даже когда в очереди еще имеется место.

    Следует помнить, что установка пакета в очередь или его отбрасывание согласно правилам RED/WRED (или FQ) осуществляется на уровне IP-протокола (ведь именно он содержит поле заголовка DSCP или метку потока).

    Алгоритм RED использует взвешенное значение длины очереди в качестве фактора, определяющего вероятность отбрасывания пакета. По мере роста средней длины очереди растет вероятность отбрасывания пакетов. Если средняя длина очереди меньше определенного порога, вероятность отбрасывания пакета равна нулю (см. рис. 2.12). Небольшие кластеры пакетов могут успешно пройти через фильтр RED. Более крупные кластеры могут понести потери. Это приводит к тому, что ТСР-сессии с большими открытыми окнами имеют большую вероятность отбрасывания пакетов.

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

    Интересное предложение относительно выборочного (приоритетного) отбрасывания пакетов содержится в работе [2.36] в отношении мультимедиа-потоков.

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

    RED пытается увеличить число коротких перегрузок и избежать долгих.

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

    Существует модификация алгоритма обработки очередей WRED (Weighted Random Early Detection), широко используемая в маршрутизаторах. Этот алгоритм применяется и при реализации DiffServ и гарантированной переадресации (AF), когда решение об обработке пакета принимается в каждом транзитном узле независимо (PHB). При этом может учитываться код DSCP IP-заголовка.

    Алгоритм WRED удобен для адаптивного трафика, который формируется протоколом ТСР, так как здесь потеря пакетов приводит к снижению темпа их передачи отправителем. Алгоритм WRED присваивает пакетам не IP типа нулевой приоритет, повышая вероятность потери таких пакетов. Имеется возможность конфигурации DWRED и DWFQ для одного и того же интерфейса.

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

    (рис 2.12)

    WRED статистически отбрасывает больше пакетов для сессий с большими потоками. По этой причине ТСР-отправители больших потоков будут вынуждены в большей степени понизить поток, чем отправители малого трафика.

    Ни АТМ-интерфейсы маршрутизаторов, ни АТМ-коммутаторы не предоставляют гарантий QoS для UBR виртуальных каналов. Маршрутизатор CISCO может специфицировать только пиковую скорость передачи (PCR) для UBR-канала.

    Маршрутизатор автоматически определяет параметры, которые нужно использовать в вычислениях WRED. Среднее значение длины очереди определяется на основе предыдущего значения и текущего размера очереди, согласно формуле:

    Средняя длина очереди = (old_evarage $$\times$$ (1-2-n)) + (current_{queuesize} $$\times$$ 2-n),

    где n - экспоненциальный весовой фактор, конфигурируемый пользователем. В некоторых статьях о WRED значение 2n обозначается qw.

    Большое значение n сглаживает пики и провалы длины очереди. Средняя длина очереди не будет меняться быстро. Процесс WRED не сразу начнет отбрасывать пакеты при перегрузке, зато продолжит отбрасывание, даже когда перегрузки уже нет (очередь уже сократилась ниже минимального порога). Когда n становится слишком большим, WRED не будет реагировать на перегрузку. Пакеты будут посылаться или отбрасываться так, как если бы WRED не работал.

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

    Вероятность отбрасывания пакета зависит от минимального порога, максимального порога и маркерного деноминатора вероятности. Когда средняя длина очереди выше T1 (Min1, Min2 на рис. 2.12), RED начинает отбрасывать пакеты. Частота отбрасываний увеличивается линейно по мере роста длины очереди до тех пор, пока усредненный размер очереди не достигнет T2 (Max1 и Max2).

    Маркерный деноминатор вероятности pc равен доле теряемых пакетов, когда средняя длина очереди равна T2. Например, если pc равен 1/512, один из 512 пакетов отбрасывается, когда средняя длина очереди достигает T2 (см. рис. 2.13 ниже). Когда длина очереди превышает T2, отбрасываются все пакеты. Минимальный порог T1 следует выбрать достаточно высоким, чтобы максимизировать использование канала.

    Разница между T2 и T1 должна быть достаточно велика, чтобы избежать глобальной синхронизации ТСР агентов (синхронное изменение CWND).

    (рис 2.13)

    В качестве альтернативы можно рассмотреть ситуацию, когда маршрутизатор осуществляет пометку пакетов с помощью битафлага СЕ (Congestion Experienced). Отправитель должен реагировать на этот флаг так, как если бы произошла потеря пакета. Этот механизм, называемый ECN (Explicit Congestion Notification), использует двухбитную схему оповещения, занимая биты 6 и 7 в поле ToS заголовка IPv4 (или два неиспользуемые бита в поле IP Differentiated Services). Бит 6 устанавливается отправителем с целью индикации того, что эта система совместима с ECN (бит ECN ). Бит 7 является СЕ-битом и устанавливается маршрутизатором, когда размер очереди превышает заданное при конфигурации значение. ECN-алгоритм реализует в маршрутизаторе RED. Когда какой-то пакет выбран, он помечается битом СЕ, если в нем установлен бит ECN, - в противном случае пакет отбрасывается.

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

    Исходный диалог установления соединения ТСР при реализации данного алгоритма предполагает добавление возможности ECN-эха и CWR (Congestion Window Reduced) для уведомления партнера о возможности работы с СЕ-битом. Отправитель устанавливает бит ECN во всех посылаемых пакетах. Если отправитель получит ТСР-сегмент с флагом ECN-эхо, он должен подстроить ширину CWND в соответствии с алгоритмом быстрого восстановления при потере одиночного пакета. Следующий посланный пакет должен иметь CWRфлаг, оповещающий получателя о его реакции на перегрузку. Отправитель реагирует подобным образом, по крайней мере, один раз за время RTT. Далее ТСР-пакеты с установленным флагом ECN не вызывают никакой реакции в пределах интервала RTT. Получатель устанавливает ECN-флаг во всех пакетах, когда он получает пакет с установленным битом СЕ. Это продолжается до тех пор, пока он не получит пакет с флагом CWR, указывающим на реакцию отправителя на перегрузку. ECN-флаг устанавливается только в пакетах, которые содержат поле данных. Пакеты ТСР ACK, которые не имеют поля данных, должны содержать флаг ECN=0.

    Соединение не должно ждать получения трех ACK, чтобы детектировать перегрузку. Вместо этого получатель уведомляется о зарождающейся ситуации перегрузки путем установления соответствующего бита, который в свою очередь вызывает соответствующий отклик. Широкое использование ECN в ближайшее время не ожидается, во всяком случае, в контексте IPv4. По этой причине не принято никакого стандарта для позиционирования соответствующих бит в IP-заголовке.

    ECN предоставляет некоторое улучшение эксплуатационных характеристик канала по сравнению со схемой RED, в частности, для коротких ТСР-транзакций. Главной особенностью алгоритма ECN является необходимость изменения программ работы, как маршрутизатора, так и стека TCP/IP. Выгоды этого алгоритма могут стать заметными лишь при достаточно широком внедрении. Можно ожидать более быстрого по отношению ECN распространения алгоритма RED, так как он требует лишь локальной модификации программного обеспечения маршрутизатора.

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

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

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

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

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

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

    Если потеря из-за перегрузки происходит на ранней фазе медленного старта, в сети недостаточно пакетов, чтобы сгенерировать три дублированных ACKотклика для запуска быстрой повторной пересылки и быстрого восстановления. Вместо этого отправитель должен подождать таймаута RTO (минимальное время равно одной секунде). Для коротких сессий длиной (67) RTT ~ нескольких миллисекунд издержки, связанные с потерей одного пакета, слишком велики. Приблизительно 56% повторных передач осуществляется после таймаута RTO.

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

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

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

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

    Иногда возникают ситуации, когда приложение воспринимает управляющие функции ТСР слишком лимитирующими. Это может происходить, например, при управлении общедоступными коммутирующими телефонными сетями через Интернет. В таком варианте не требуется обеспечение строгой последовательности пакетов (отсутствие перепутывания порядка). Кроме того, ограниченное число TCP-сокетов усложняет поддержку приложений, использующих несколько сетевых интерфейсов, да и сам протокол ТСР уязвим для ряда атак, например, для SYN-шторма. Решение такого типа проблем возможно с привлечением протокола SCTP (Stream Control Transmission Protocol).

    Основное отличие между SCTP и TCP проявляется на фазе инициализации, когда партнеры SCTP обмениваются списком оконечных адресов (IP-адресов и номеров портов), которые ассоциируются с текущей сессией. Стартовая процедура SCTP также отличается от традиционного диалога. Здесь получатель не выделяет никаких ресурсов для соединения, что делает процедуру более устойчивой против атак типа SYN-шторма. Инициатор соединения может, в конце концов, откликнуться, послав COOKIEECHO, куда вкладывается порция данных. Таким образом, информационный обмен начинается уже на фазе формирования виртуального соединения. С этого момента сессия считается открытой.

    Закрытие сессии SCTP также отличается от ТСР. В SCTP закрытие сессии с одной стороны означает опустошение очередей и прекращение посылки данных с другой стороны. Здесь через одну и ту же ассоциацию транспортного уровня может осуществляться несколько обменов. Порядок сообщений в рамках одного обмена неукоснительно соблюдается. Каждый поток имеет однозначную идентификацию. Протокол SCTP поддерживает также доставку вне очереди, когда пакет помечается для немедленной доставки, и тогда он получает приоритет и будет доставлен раньше, чем это предписывалось его порядковым номером. Протокол SCTP требует предварительного выяснения значения MTU. таймер повторных передач, запускаемый при посылке каждого сегмента, предусмотрен в SCTP, как и в TCP. Получатель SCTP использует режим подтверждений SACK, реализуемый для каждого второго полученного сегмента. Если сообщение оказалось в зазоре между SACK, после трех таких откликов отправитель повторно посылает это сообщение и сокращает вдвое CWND.

    Применение обменов точка-мультиточка предполагает, что каждый оконечный адрес, ассоциированный с одной и той же ЭВМ, не обязательно использует один и тот же путь. Поэтому для каждой конечной точки периодически должна производится проверка осуществимости связи (процедура keepalive ).

    Идея совмещения состояния ТСР перегрузки для нескольких каналов применима и для смеси потоков с гарантией и без гарантии доставки, осуществляющих одновременно обмен между общими конечными пунктами. Именно такая схема мультиплексирования реализуется в модели менеджера перегрузки. Менеджер перегрузки представляет собой модуль оконечной системы, который позволяет набору одновременных потоков от ЭВМ к некоторой точке назначения совместно использовать общую систему управления перегрузкой.

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

    Реализация общей функции управления перегрузкой может базироваться на механизме отзыва (callback), когда приложение посылает запрос менеджеру перегрузки (МП). МП откликается посылкой отзыва, и приложение после этого может послать информационный сегмент протокольному драйверу.

    Другой поддерживаемый механизм МП называется синхронной передачей. Здесь МП предоставляет приложению данные о состоянии канала (пропускная способность, RTT и т.д.) и оно может осуществить запрос, лишь когда состояние сети изменится существенным образом (пороги по базовым параметрам задаются при конфигурации). Удаленная ЭВМ информирует МП о числе полученных и потерянных байтов, о результатах измерения RTT, проведенных на уровне приложения. Приложение предоставляет информацию о причинах потерь (истечение таймаута, состояние транзитных сетей или отбрасывание на основе ECN-флагов).

    В последнее время появилось достаточно много версий протокола "лучше чем ТСР", большинство из них предлагаются в комплекте с WEBсервером. Чаще всего это модифицированные версии ТСР - например, за счет таймера более высокого разрешения, позволяющего реагировать более быстро на изменения в сети. Некоторые версии предлагают большее стартовое значение CWND или более быструю версию медленного старта, где размер окна не удваивается, а утраивается на каждом из шагов (за RTT ). Сходные модификации могут быть использованы на фазе избежания перегрузки (линейный участок увеличения CWND ). Все эти модификации вынуждают отправителя вести себя более агрессивно, увеличивая давления на сетевые буферы. Возможно создание программ обмена, где, например, при копировании через сеть файла формируется не одно, а несколько виртуальных соединений. Такого рода решения дают выигрыш главным образом за счет ухудшения условий реализаций других одновременных сессий. Это противоречит общей философии Интернет (Интернет - это клуб джентльменов). Но на самом деле агрессивное поведение ТСР приложения в конечном итоге делает его неэффективным (менее эффективным, чем стандартный ТСР). Как правило, такие решения приводят к большим потерям пакетов, так как их усилия максимально загрузить ресурсы сети заканчиваются понижением чувствительности к сигналам перегрузки. Если же таких приложений в Интернет станет много, это приведет к серьезной деградации пропускной способности каналов из-за перегрузки. Приемлемыми усовершенствованиями ТСР можно признать только такие, которые не ухудшают условий работы для окружающих. Это наилучшая стратегия, так как позволяет использовать ресурсы сети более эффективно для всех участников.

    Работа протокола TCP AIMD в режиме исключения перегрузок можно характеризовать формулой [2.1]:

    $$BW= \frac{MSS} {(RTT \times \sqrt{(1.33 \times p)}) + (RTO \times p \times [1+32 \times p^2] \times \min (1,3 \times \sqrt{0.75 \times p)})}$$

    где BW - полоса пропускания;

    MSS - максимальный размер сегмента в байтах, используемый сессией;

    RTO - таймаут повторной пересылки;

    p - частота потери пакетов (0.01 означает 1% потерь)

    Эта формула является наилучшей аппроксимацией. Некоторое упрощение формулы можно получить, считая RTO=5*RTT.

    Еще более упрощенная формула может быть взята из работы [2.31].

    $$BW= 0.93 \times \frac{MSS}{RTT \sqrt{p}}$$

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

  • Окно получателя не ограничивает рабочих характеристик соединения.
  • Обе формулы позволяют полосе достигать бесконечности при нулевых потерях.
  • Значение RTT является средним и включает в себя задержку, сопряженную с пребыванием пакета в очереди.
  • Формулы работают только для одного ТСР-соединения. Если через канал осуществляется несколько ТСРсоединений, каждое из них следует указанным формулам.
  • Формулы предполагают долговременные ТСР-соединения. Для особо коротких соединений ( <10 пакетов ), когда нет потерь, работает алгоритм медленного старта. Для сессий промежуточной длительности, где в среднем теряется несколько сегментов, параметры окажутся несколько лучше, чем предсказывают формулы.
  • Различие между простой и сложной формулами заключается в том, что сложная формула учитывает влияние таймаутов повторных передач. Для низкого уровня потерь ( <1% ), таймауты обычно не происходят и формулы дают практически идентичные результаты. При высоких потерях ( $$\ge 1%$$ сложная формула дает большую точность оценки.
  • Выводы

  • TCP уязвимость в отношении случайных потерь делает трудным мультиплексирование информационного потока с трафиком реального времени при заметных временных вариациях скорости передачи (например, мультимедиа), в особенности, если оба вида трафика работают с общим буфером, что типично для большинства современных сетей. В сетях ATM, однако, TCP соединения могут поддерживаться с помощью классов трафика UBR или ABR, которые обычно буферизуются отдельно от высоко приоритетного VBR (Variable Bit Rate) или CBR (Constant Bit Rate) трафика. Если последние классы трафика имеют более высокий приоритет, TCP соединения обнаружат для себя емкость канала, варьируемую со временем, оставшуюся после обслуживания потоков VBR и CBR. Эти вариации могут приводить к "случайным потерям", которые сильно ухудшают рабочие характеристики. Однако если буфер имеет достаточный объем, чтобы сгладить эти вариации и удержать вероятность потери для соединения "точка--точка" ниже обратного квадрата произведения полосы на задержку, то рабочие характеристики TCP не будут серьезно ухудшены. Включение селективного подтверждения в TCP облегчит эту проблему, так как размер окна не нужно резко сокращать для изолированных случайных потерь.
  • В дополнение к уязвимости от случайных потерь, тот факт, что потери являются основным средством обратной связи, используемым TCP, приводит к непомерным задержкам. Это происходит потому, что в сетях с высоким коэффициентом использования размер окна для TCP соединения будет увеличиваться и, после того как возможности узкого участка канала окажутся полностью исчерпанными, а буфер переполненным, произойдет потеря. Задержка и рабочие характеристики при потерях могут быть существенно улучшены, если мы вместо этого используем схему, которая лишь пытается поддерживать ширину окна, чтобы достичь высокого использования канала. Такая схема, как DECbit [2.26], реализует это, используя явную обратную связь со стороны коммутаторов; подобные схемы имеет смысл рассмотреть, особенно потому, что Explicit Congestion Notification (явное оповещение о перегрузке) встроена в качестве опции для сетей ATM. Заметим, однако, что схема DECbit, в частности, подвержена, как и TCP, проблемам при работе с соединениями при больших задержках распространения. Другой возможностью является более изощренная оценка RTT, сходная с тем, что сделано в работе [2.22]. Это, конечно, привлекательно, так как исключает необходимость явной обратной связи. Однако если задержка RTT может меняться существенно без изменения загрузки в канале (например, из-за того, что задержка обработки в узлах зависит от загрузки операционной системы или потому, что задержки связаны с особенностями работы мобильных приложений), тогда адаптация, базирующаяся на обработке задержек, может оказаться менее устойчивой, чем адаптация на основе потерь или явной обратной связи. Кроме того, если различные соединения не изолированы друг от друга с точки зрения использования ими полосы и сетевых буферов, тогда соединение, которое более агрессивно в отношении получения полосы и поднимающее скорость передачи до тех пор, пока не произойдет потеря, забьет соединения, которые анализируют RTT, чтобы избежать перегрузки. Таким образом, изменения на транспортном уровне должны либо адаптироваться универсально, либо тесно сотрудничать с сетевым уровнем, отслеживающим "алчные" соединения.
  • Использование групповых подтверждений в TCP мотивирует в TCPtahoe сокращение ширины окна до единицы после потери, чтобы избежать всплеска потока пакетов из-за повторной их передачи. Это, в свою очередь, приводит к экспоненциальному увеличению размера окна при медленном старте, необходимому для сетей с большим произведением полосы на задержку. С другой стороны, это экспоненциальное увеличение вызывает серьезные флуктуации трафика, которые, если размер буфера меньше, чем 1/3 от произведения полосы на задержку, вызывает переполнение буфера и второй медленный старт, понижая пропускную способность. TCP-reno пытается избежать этого явления путем сокращения окна вдвое при обнаружении потери. В то время как это при идеальных условиях обеспечивает улучшенную пропускную способность, TCP-reno в его нынешнем виде слишком уязвим для фазовых эффектов и множественной потери пакетов, чтобы стать заменителем для TCP-tahoe. Основной проблемой с TCP-reno является то, что могут быть множественные ограничения на окно, связанные с одним эпизодом перегрузки, и что множественные потери могут приводить к таймауту (который на практике вызывает значительное снижение пропускной способности, если используются таймеры с низким разрешением). Версия TCP-Vegas [2.4,9] пытается реализовать ряд усовершенствований, таких, как более изощренная обработка и оценка RTT. Но для флуктуаций RTT в Интернет существует много других причин помимо заполнения буфера. Для того, чтобы существенно улучшить существующие версии TCP, необходимо избегать резких сокращений размеров окна как в TCP-tahoe, так и в TCP-reno за исключением случая, когда имеет место продолжительная перегрузка (которая вызывает массовые потери пакетов). Одним возможным средством обработки изолированных потерь без изменения размера окна является использование некоторой формы селективного подтверждения. В ожидании разработки удовлетворительного нового варианта предлагается применять TCPtahoe (в сочетании с управлением сетевого уровня, чтобы оптимизировать рабочие характеристики), так как этот вариант несравненно устойчивей, чем TCPreno.
  • Несовершенство TCP для соединений с высокими задержками распространения может вызвать проблемы при мультиплексировании потоков на короткие и дальние расстояния в WAN. Короче говоря, эти эксплуатационные проблемы могут не проявиться, так как WAN может быть существенно недогружена и там может не оказаться узких мест (т.e. размер окна, необходимый для хорошей работы, может быть слишком мал, чтобы вызвать переполнение буфера, и поэтому достигается максимальная стационарная пропускная способность). Однако, для гарантирования рабочих характеристик в высоко загруженных сетях, каждое TCP соединение должно иметь зарезервированный буфер и полосу пропускания вдоль всего сетевого маршрута. Обычно выделение ресурсов осуществляется при формировании соединения и заставляет коммутаторы и маршрутизаторы формировать независимые очереди для каждого соединения [2.11], [2.25]. Так как администрирование ресурсов по принципу "наилучшего возможного" может оказаться весьма дорогим, более приемлемой альтернативой может быть резервирование ресурсов для каждого класса трафика. В такой ситуации несовершенство будет сохраняться, если TCP поддерживается поверх ATM с классом трафика UBR. Однако если TCP поддерживается поверх класса трафика ABR, варьирующаяся со временем скорость передачи, доступная для каждого соединения, определяется на сетевом уровне и администрируется отправителем, так, чтобы различные TCP соединения были изолированы друг от друга, даже если они совместно используют буферы.
  • Так как предубеждение против соединений с большими задержками RTT связано с механизмом адаптации окна, оно в принципе может быть преодолено путем модификации механизма мониторирования полосы во время фазы избежания перегрузки, например, путем увеличения размера окна так, чтобы темп увеличения пропускной способности для всех соединений был одним и тем же (такая схема была рассмотрена, но не рекомендована в [2.13]). Однако невозможно выбрать универсальный временной масштаб для настройки окна, который бы работал для сетей с разной пропускной способностью и топологией. Во-первых, зондирование дополнительной полосы с темпом 1 Mбит/с в секунду может быть слишком быстрым для сети с каналом 1 Mбит/с, но слишком медленным для гигабитной сети. Таким образом, чтобы заставить работать такую схему, некоторый обмен между сетевым и транспортным уровнем был бы крайне существенным. Во-вторых, такая схема будет все же подвержена сильному воздействию некоторых недостатков TCP, таких, как деградация рабочих характеристик при наличии случайных потерь и чрезмерных задержек, связанных с попытками использования дополнительной полосы в условиях полного использования канала. Таким образом, эта модификация не может считаться лучшим подходом к проблеме оптимальности.
  • Суммируя, можно сказать, что мы идентифицировали несколько недостатков TCP, мы также представили возможные средства получения хороших рабочих характеристик посредством решений сетевого уровня, таких, как изоляция соединений друг от друга и предоставление буферов достаточного объема, чтобы устранить быстрые вариации доступной канальной емкости. Но нужно помнить, что нельзя увеличивать объем буфера беспредельно, так как это может привести к таймаутам и, в конечном итоге, к большим потерям пропускной способности. Особенно интересным является вопрос, как наилучшим образом поддержать TCP поверх ATM классов услуг ABR и UBR, так как это включает адаптацию сетевого и транспортного уровней. Другой важной областью исследований является разработка альтернативного механизма управления окном, который устранит некоторые недостатки TCP, сохранив его децентрализованную структуру. Децентрализованное адаптивное управление скоростью передачи, при сохранении справедливости распределения ресурсов, - задача трудная, если вообще возможная, но некоторое улучшение TCP несомненно реально. Возможные усовершенствования могут превзойти алгоритм исключения перегрузки за счет более изощренной оценки задержек RTT и использования селективного подтверждения, чтобы улучшить рабочие характеристики при наличии случайных потерь.

    Здесь уместно сказать, что радикальным решением могло бы быть исчерпывающее информирование отправителя о состоянии и динамике заполнения всех буферов вдоль виртуального соединения. Такой алгоритм можно реализовать лишь при условии, что все сетевое оборудование вдоль виртуального пути способно распознавать сегменты отклики и выдавать требующиеся данные в рамках определенного протокола (в том числе и оборудование уровня L2!). Здесь предполагается, что маршрут движения сегментов туда и обратно идентичны. В последнее время появилось оборудование L2 (Ethernet), способное фильтровать трафик по IP-адресам и даже номерам портов (а это уже уровень L4). Так что решение уже не представляется чем-то совершенно фантастическим. Такие сетевые приборы могли бы помещать в пакеты откликов ACK информацию о состоянии своих буферов. Учитывая, что объемы буферов в разных устройствах могут отличаться весьма сильно, имеет смысл выдавать не число занятых позиций, а относительную долю занятого буферного пространства. Проблема здесь в том, что длительное время даже в локальных сетях, я уже не говорю про Интернет, будут сосуществовать сетевые устройства, как поддерживающие этот новый протокол, так и старые - не поддерживающие. Но даже в таких условиях этот протокол будет давать заметный выигрыш. Ведь новые устройства будут ставиться в первую очередь именно в "узких" местах сети, где потери были наиболее значимы. Условия загрузки нового устройства останутся теми же, но о них отправитель получит исчерпывающую информацию и за счет этого сможет оптимизировать трафик. При этом отправитель должен отслеживать не просто состояние на текущий момент, но и темп заполнения и освобождения буферов. Ширина окна в таком случае может определяться на основе прогноза состояния буфера на момент, когда туда придет соответствующий ТСРсегмент. Для этого отправителю придется выделить дополнительную память для хранения уровней заполнения буферов. Задержка в цепи отслеживания состояния тракта при этом будет минимальной. Существенный выигрыш могут получить сервис провайдеры с однородной структурой оборудования.

    Проблема усложнена разнообразием технологий L2, ведь трудно себе представить, что нужную информацию о состоянии буферов будет выдавать ATM или SDH. Но наметившаяся тенденция использования Ethernet не только в LAN, но и в региональных сетях, может упростить задачу.

    Альтернативой этому алгоритму могла бы служить схема, где каждому виртуальному соединению в каждом вовлеченном сетевом устройстве (включая L2) выделяется свой независимый буфер известного объема.

    Любое из названных решений требует замены огромного объема оборудования. Но, вопервых, раз в 25 лет оборудование все равно обновляется, вовторых, это даст выигрыш в пропускной способности не менее двух раз и существенно упростит задачу обеспечения требуемого уровня QoS.

    Первым шагом на пути внедрения отслеживания уровня заполнения буфера может служить ECN-алгоритм, описанный выше.

    Разрабатывая новые версии драйверов ТСР-протокола, надо с самого начала думать и о сетевой безопасности, устойчивости программ против активных атак.

    Новые трудности в реализации модели протокола ТСР возникли при работе с современными быстрыми (110 Гбит/с) и длинными ( RTT>200мсек ) каналами. Для пакетов с длиной 1500 байт время формирования окна оптимального размера достигает 83333 RTT (режим предотвращения перегрузки), что при RTT=100 мсек составляет 1,5 часа! При этом требования к вероятности потери пакетов становятся невыполнимыми. В норме для таких каналов BER лежит в пределах 10-7 - 10-8. Разрешение проблемы возможно путем использования опции Jumbo пакетов или за счет открытия нескольких параллельных ТСРсоединений. В последнее время предложено несколько новых моделей реализации ТСР: High Speed TCP (HSTCP - S.Floyd), Scalable TCP (STCP - T.Kelly), FAST (http://datatag.web.cern.ch/datatag/pfldnet2003/papers/ low.pdf), XCP (http://portal.acm.org/citation.cfm?doid=633035), SABUL (Y.Gu, X.Hong). Модификации HSTCP и STCP характеризуются тем, что при нескольких потоках с разными RTT они некорректно распределяют полосу. В этих условиях заметные трудности создает синхронизация потерь для конкурирующих потоков. Специально для случая высокой скорости и больших задержек разработана модификация BI-TCP (Binary Increase TCP - http://www.csc.ncsu.edu/faculty/rhee/export/bitcp.pdf, Lisong Xu, Khaled Harfoush and Injong Rhee, Binary Increase Congestion Control for Fast, Long Distance Networks). Протокол BI-TCP имеет следующие свойства:

  • Масштабируемость. Протокол может масштабировать свою долю полосы до 10 Гбит/c при BER ~ 3,5?108 .
  • RTT (равенство условий). При больших значениях окна его RTT неэквивалентность (unfairness) пропорциональна RTT-отношению (как в случае AIMD).
  • TCP дружественность. Протокол достигает ограниченной ТСР-эквивалентности для всех размеров окна. Для высокой вероятности потерь, где ТСР работает хорошо, ТСРдружественность сопоставима с STCP.
  • Эквивалентность (fairness) и сходимость. По сравнению с HSTCP и STCP, он позволяет получить большую эквивалентность полос пропускания в широком временном диапазоне и быструю сходимость к уровням справедливых долей.
  • AIMD демонстрирует квадратичный рост пропускной способности при увеличении отношения RTT (линейный рост "несправедливости"). Для других протоколов степень несправедливости еще выше.

    Функция отклика протокола на перегрузку определяется отношением скоростей передачи пакетов в зависимости от вероятности их потери.

    BI-TCP встраивается в TCPS-ACK. В протоколе используются следующие фиксированные параметры:

    Low_window - если размер окна больше чем этот порог, используется BI-TCP, в противном случае - обычный ТСР;

    Smax - максимальное приращение;

    Smin - минимальное приращение;

    $$\beta$$ - мультипликативный коэффициент сокращений ширины окна;

    default_max_win - значение максимума окна по умолчанию

    В протоколе используются следующие параметры:

    max_win - максимальное значение ширины окна, в начале равно величине по умолчанию;

    min_win - минимальная ширина окна;

    prev_win - максимальное значение ширины окна до установления нового максимума;

    target_win - средняя точка между максимумом и минимумом ширины окна;

    Cwnd - размер окна перегрузки;

    is_BITCP_ss - Булева переменная, указывающая, находится ли протокол в режиме медленного старта. В начале = false ;

    ss_cwnd - переменная, отслеживающая эволюцию cwnd при медленном старте;

    ss_target - значение cwnd после одного RTT при медленном старте BI-TCP.

    При входе в режим быстрого восстановления:

    if (low_window <= cwnd) {
    	prev_max = max_win;
    	max_win = cwnd;
    	cwnd = cwnd *(1?);
    	min_win = cwnd;
    	if (prev_max > max _win) //Fast. Conv.
    	max_win = (max_win + min_win)/2;
    	target_win = (max_win + min_win)/2;
    } else {
    	cwnd = cwnd*0,5; //normal TCP

    Когда система не находится в режиме быстрого восстановления и приходит подтверждение для нового пакета, то:

    if (low_window > cwnd) {
    	cwnd =cwnd + 1/cwnd; // normal TCP
    	return
    }
    if (is_BITCP_ss is false) { //bin.increase
    	if (target_win  cwnd < Smax) // bin.search
    		cwnd += (target_win  cwnd)/cwnd;
    	else
    		cwnd += Smax/cwnd; // additive incre.
    	if (max_win > cwnd) {
    		min_win = cwnd;
    	target_win = (max_win + min_win)/2;
    	} else {
    		is_BITCP_ss = true
    		ss_cwnd =1;
    		ss_target = cwnd+1;
    		max_win = default_max_win;
    	}
    } else {
    	cwnd = cwnd + ss_cwnd/cwnd;
    	if(cwnd >= ss_target) {
    		ss_cwnd = 2*ss_cwnd; ss_target = cwnd + ss_cwnd;
    	}
    		if(ss_cwnd >= Smax)
    		is_BITCP_ss = false;
    }

    2.2.1.5. Характеристики BI-TCP

    При анализе характеристик протокола предполагается, что потери пакетов происходят с вероятностью 1/р. Авторы определяют эпоху перегрузки как время между двумя последовательными потерями пакетов.

    Пусть Wmax обозначает размер окна непосредственно перед потерей пакета. После потери размер окна уменьшается до $$W_{max}(1 - \beta)$$. BI-TCP переключается от аддитивного увеличения к двоичному поисковому увеличению окна, когда различие между текущим значением ширины окна и конечным значением ( target ) меньше Smax. Так как конечное (target) значение ширины окна является средней точкой между Wmax и текущим значением ширины окна, можно сказать, что BI-TCP переключается между этими двумя приращениями, когда разница между текущей шириной окна и Wmax меньше 2Smax. Ниже в таблицах 2.2 и 2.3 представлены расчетные характеристики протоколов AIMD, BITCP, HSTCP и STCP для каналов с быстродействием 100 и 2500 Мбит/c.

    Отношения пропускной способности протоколов при 100Мбит/c
    отношение RTT 1 3 6
    AIMD 0,99 7,31 26,12
    BI-TCP 0,94 13,06 33,81
    HSTCP 1,13 10,42 51,09
    STCP 1,12 27,84 72,74

    На рис. 2.14 приведены расчетные данные для откликов при использовании разных модификаций протокола ТСР.

    Отношения пропускной способности протоколов при 2,5Гбит/c
    отношение RTT 1 3 6
    AIMD 1,05 6,56 22,55
    BI-TCP 0,96 9,18 35,76
    HSTCP 0,99 47,42 131,03
    STCP 0,92 140,52 300,32
    (рис 2.14) Сравнение функций отклика для разных протоколов (http://www.csc.ncsu.edu/faculty/rhee/export/bitcp.pdf)

    Еще более радикальным является предложение нового транспортного протокола, описанное в http://book.itep.ru/4/44/ new_tcp.htm.

    Список документов RFC, посвященных протоколу TCP, начиная с 1997 года

    2018 TCP Selective Acknowledgement Options. M. Mathis, J. Mahdavi, S. Floyd, A. Romanow. October 1996.

    2042 Registering New BGP Attribute Types. B. Manning. January 1997.

    2126 ISO Transport Service on top of TCP (ITOT). Y. Pouffary, A. Young. March 1997.

    2140 TCP Control Block Interdependence. J. Touch. April 1997.

    2309 Recommendations on Queue Management and Congestion Avoidance in the Internet. B. Braden, D. Clark, J. Crowcroft, B. Davie, S. Deering, D. Estrin, S. Floyd, V. Jacobson, G. Minshall, C. Partridge, L. Peterson, K. Ramakrishnan, S. Shenker, J. Wroclawski, L. Zhang. April 1998.

    2398 Some Testing Tools for TCP Implementors. S. Parker, C. Schmechel. August 1998. (Also FYI0033)

    2414 Increasing TCP's Initial Window. M. Allman, S. Floyd, C. Partridge. September 1998.

    2415 Simulation Studies of Increased Initial TCP Window Size. K. Poduri, K. Nichols. September 1998.

    2416 When TCP Starts Up With Four Packets Into Only Three Buffers. T. Shepard, C. Partridge. September 1998.

    2488 Enhancing TCP Over Satellite Channels using Standard Mechanisms. M. Allman, D. Glover, L. Sanchez. January 1999. (Also BCP0028)

    2525 Known TCP Implementation Problems. V. Paxson, M. Allman, S. Dawson, W. Fenner, J. Griner, I. Heavens, K. Lahey, J. Semke, B. Volz. March 1999.

    2581 TCP Congestion Control. M. Allman, V. Paxson, W. Stevens. April 1999.

    2582 The NewReno Modification to TCP's Fast Recovery Algorithm. S. Floyd, T. Henderson. April 1999.

    2675 IPv6 Jumbograms. D. Borman, S. Deering, R. Hinden. August 1999.

    2760 Ongoing TCP Research Related to Satellites. M. Allman, Ed., S. Dawkins, D. Glover, J. Griner, D. Tran, T. Henderson, J. Heidemann, J. Touch, H. Kruse, S. Ostermann, K. Scott, J. Semke. February 2000.

    2760 Ongoing TCP Research Related to Satellites. M. Allman, Ed., S. Dawkins, D. Glover, J. Griner, D. Tran, T. Henderson, J. Heidemann, J. Touch, H. Kruse, S. Ostermann, K. Scott, J. Semke. February 2000.

    2873 TCP Processing of the IPv4 Precedence Field. X. Xiao, A. Hannan, V. Paxson, E. Crabbe. June 2000.

    2883 An Extension to the Selective Acknowledgement (SACK) Option for TCP. S. Floyd, J. Mahdavi, M. Mathis, M. Podolsky. July 2000.

    2923 TCP Problems with Path MTU Discovery. K. Lahey. September 2000.

    2988 Computing TCP's Retransmission Timer. V. Paxson, M. Allman. November 2000.

    3042 Enhancing TCP's Loss Recovery Using Limited Transmit. M. Allman, H. Balakrishnan, S. Floyd. January 2001.

    3081 Mapping the BEEP Core onto TCP. M. Rose. March 2001.

    3168 The Addition of Explicit Congestion Notification (ECN) to IP. K. Ramakrishnan, S. Floyd, D. Black. September 2001.

    3293 General Switch Management Protocol (GSMP) Packet Encapsulations for Asynchronous Transfer Mode (ATM), Ethernet and Transmission Control Protocol (TCP). T. Worster, A. Doria, J. Buerkle. June 2002.

    3390 Increasing TCP's Initial Window. M. Allman, S. Floyd, C. Partridge. October 2002.

    3448 TCP Friendly Rate Control (TFRC): Protocol Specification. M. Handley, S. Floyd, J. Padhye, J. Widmer. January 2003.

    3449 TCP Performance Implications of Network Path Asymmetry. H. Balakrishnan, V. Padmanabhan, G. Fairhurst, M. Sooriyabandara. December 2002.

    3465 TCP Congestion Control with Appropriate Byte Counting (ABC). M. Allman. February 2003

    3481 TCP over Second (2.5G) and Third (3G) Generation Wireless Networks. H. Inamura, Ed., G. Montenegro, Ed., R. Ludwig, A. Gurtov, F. Khafizov. February 2003.

    351 A Conservative Selective Acknowledgment (SACK)based Loss Recovery Algorithm for TCP. E. Blanton, M. Allman, K. Fall, L. Wang. April 2003.

    3522 The Eifel Detection Algorithm for TCP. R. Ludwig, M. Meyer. April 2003.

    3708 Using TCP Duplicate Selective Acknowledgement (DSACKs) and Stream Control Transmission Protocol (SCTP) Duplicate Transmission Sequence Numbers (TSNs) to Detect Spurious Retransmissions. Blanton, E. and M. Allman, February 2004.

    3782 The NewReno Modification to TCP's Fast Recovery Algorithm. Floyd, S., Henderson, T., and A. Gurtov. April 2004.

    Вернуться к учебному плану