Читаем Компьютерные сети. 5-е издание полностью

39.    Целью данного упражнения является реализация механизма обнаружения ошибок с помощью стандартного алгоритма циклического избыточного кода (CRC), описанного в тексте. Напишите две программы: генератор (generator) и верификатор (verifier). Программа-генератор считывает со стандартного устройства ввода я-битное сообщение из нулей и единиц, представленных в виде строки ASCII-текста. Вторая строка является k-битным многочленом (также в ASCII). На устройстве вывода печатается текст из я + k нулей и единиц, представляющий собой сообщение, подлежащее пересылке. Затем печатается многочлен в том же виде, в каком он был считан. Программа-верификатор считывает результат работы генератора и выводит сообщение, в котором сообщается, корректен ли данный результат. Наконец, напишите программу (alter), вносящую сбой, а именно инвертирующую только один бит первой строки, в зависимости от аргумента (например, порядкового номера бита, предполагая, что слева располагается бит с номером 1). Все остальные данные передаются без изменений. Набрав в командной строке generator

Глава 4

Подуровень управления доступом к среде

Все сетевые технологии могут быть разделены на две категории: использующие соединения от узла к узлу и сети с применением широковещания. Двухточечные связи мы рассматривали в главе 2; эта глава посвящена широковещательным каналам и их протоколам.

Главной проблемой любых широковещательных сетей является вопрос о том, как определить, кому предоставить канал, если пользоваться им одновременно хотят несколько компьютеров. Для примера представьте себе конференцию, в которой принимают участие шесть человек, причем каждый использует свой телефон. Все они соединены таким образом, что каждый может слышать всех остальных. Весьма вероятно, что когда один из них закончит свою речь, сразу двое или трое начнут говорить одновременно, тем самым создав неловкую ситуацию. При личной встрече подобные проблемы предотвращаются внешними средствами, например поднятием руки для получения разрешения говорить. Когда доступен лишь один канал, определить, кто может говорить следующим, значительно труднее. Для решения этой проблемы разработано множество протоколов, которые и будут обсуждаться в данной главе. В литературе широковещательные каналы иногда называют каналами с множественным доступом (multiaccess channels) или каналами с произвольным доступом (random access channels).

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

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

4.1.    Проблема распределения канала

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

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

4.1.1.    Статическое распределение канала

Традиционный способ разделения одного канала, например телефонного кабеля, между многочисленными конкурирующими пользователями — в разделении емкости с помощью одной из схем мультиплексирования или уплотнения каналов, таких как FDM (Frequency Division Multiplexing — частотное уплотнение). При наличии N пользователей полоса пропускания делится на N диапазонов одинаковой ширины, и каждому пользователю предоставляется один из них. Поскольку при такой схеме у каждого оказывается свой личный частотный диапазон, то конфликта между пользователями не возникает. При постоянном небольшом количестве абонентов, каждый из которых отправляет стабильный поток или большие партии трафика, частотное уплотнение предоставляет простой и эффективный механизм распределения. Аналогичный беспроводной пример — радиостанции FM-диапазона. Каждая станция получает часть FM-полосы и использует ее почти постоянно, передавая свой сигнал.

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

Даже если предположить, что количество пользователей можно каким-то способом удерживать на постоянном уровне, то разделение канала на статические подканалы все равно является неэффективным. Основная проблема здесь состоит в том, что

если какая-то часть пользователей не пользуется каналом, то эта часть спектра просто пропадает. Они сами при этом занимают линию, не передавая ничего, и другим не дают передать данные. Статическое разделение плохо подходит для большинства компьютерных систем, в которых трафик является чрезвычайно неравномерным, с частыми пиками (вполне обычным является отношение пикового трафика к среднему как 1000:1). Следовательно, большую часть времени большая часть каналов не будет использоваться.

То, что характеристики статического частотного уплотнения оказываются неудачными, можно легко продемонстрировать на примере простых вычислений теории массового обслуживания. Для начала сосчитаем среднее время задержки T для отправки кадра по каналу емкостью C бит/с. Предполагается, что кадры прибывают в случайном порядке со средней скоростьюкадров в секунду. Длина кадров является случайной величиной, среднее значение которой равнобита. При таких параметрах скорость обслуживания канала равнакадров в секунду. Теория массового обслуживания говорит о том, что

(Для любознательных: это результат для очереди M/M/1. Требуется, чтобы случайность длительности промежутков между кадрами и длины кадров соответствовали экспоненциальному распределению или, что эквивалентно, являлись результатом пуассоновского процесса.)

В нашем примере C равно 100 Мбит/с, средняя длина кадра, ско

рость прибытия кадров X = 5000 кадров в секунду. Тогда T = 200 мкс. Обратите внимание: если бы мы не учли задержки при формировании очереди и просто посчитали, сколько времени нужно на передачу кадра длиной 10 000 бит по сети с пропускной способностью 100 Мбит/с, то получили бы неправильный ответ: 100 мкс. Это число приемлемо лишь при отсутствии борьбы за канал.

Теперь давайте разделим канал на N независимых подканалов, у каждого из которых будет пропускная способность C/N бит/с. Средняя входная скорость в каждом подканале теперь будет равнакадров в секунду. Сосчитав новое значение средней задержки T, получим:

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

Аргументы, применимые к FDM, можно отнести и к другим способам статического распределения канала. Если использовать временное уплотнение (TDM, Time Division

Multiplexing — мультиплексная передача с временным разделением) и выделять каждому пользователю N-й интервал времени, то если интервал не используется абонентом, он просто пропадает. С тем же успехом можно разделить сети физически. Если взять 100-Мбитную сеть и сделать из нее десять 10-Мбитных, статически распределив по ним пользователей, то в результате средняя задержка возрастет с 200 мкс до 2 мс.

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

4.1.2. Допущения, связанные с динамическим распределением каналов

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

1.    Независимый трафик. Модель состоит из N независимых станций (компьютеров,

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

кадров). Как только кадр сформирован, станция блокируется и ничего не делает, пока кадр не будет успешно передан.

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

3.    Наблюдаемые коллизии. Если два кадра передаются одновременно, они перекрываются по времени, в результате сигнал искажается. Такое событие называется конфликтом, или коллизией. Все станции могут обнаруживать конфликты. Искаженный вследствие конфликта кадр должен быть передан повторно. Других ошибок, кроме тех, которые вызваны конфликтами, нет.

4.    Непрерывное или дискретное время. Время может считаться непрерывным, и тогда передача кадров может начаться в любой момент. В противном случае время может быть разделено на дискретные интервалы (такты, иногда называемые слотами). Передача кадра может начаться только с началом такта. Один временной интервал может содержать 0, 1 или более кадров, что соответствует свободному интервалу, успешной передаче кадра или коллизии соответственно.

5.    Контроль несущей или отсутствие контроля. Если контроль несущей выполняется, станции могут определить, свободна или занята линия, до ее использования. Если канал занят, станции не будут пытаться передавать кадры по нему, пока он не освободится. Если контроля несущей нет, то станции не могут определить, свободна или занята линия, пока не попытаются ее использовать. Они просто начинают передачу. Только потом они могут определить, была ли передача успешной.

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

станции, так и в пределах одной станции, а также, что кадры формируются непредсказуемо, но с постоянной скоростью. В действительности, это не очень хорошая модель сетевого трафика, поскольку хорошо известно, что пакеты прибывают целыми последовательностями в определенные диапазоны временной шкалы (Paxson, Floyd, 1995; Leland и др., 1994). Тем не менее пуассоновские модели, как их часто называют, полезны, так как легко описываются математически. Они помогают анализировать протоколы, составляя общее представление об изменении производительности с течением времени и о разнице между различными реализациями.

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

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

Допущение о коллизиях является основным. Станциям необходим способ обнаружения коллизий, если они собираются повторно пересылать кадры, а не мириться с их потерей. Для проводных каналов можно использовать оборудование, умеющее определять коллизии. В этом случае станции заранее обрывают передачу, чтобы не засорять канал. В беспроводных каналах распознавать коллизии намного сложнее; об их возникновении приходится узнавать по факту, когда не прибывает ожидаемый кадр подтверждения. Также возможно успешное получение некоторых кадров, попавших в коллизию, — это зависит от типа сигнала и оборудования на получающей стороне. Подобные ситуации встречаются нечасто, поэтому будем предполагать, что все кадры, участвующие в коллизии, попросту теряются. Кроме того, мы познакомимся с протоколами, специально предназначенными для предотвращения коллизий, а не решения создаваемых ими проблем.

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

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

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

4.2. Протоколы коллективного доступа

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

4.2.1. Система ALOHA

История нашего первого MAC начинается на нетронутых цивилизацией Гавайях в 1970-х годах. В данном случае «нетронутые цивилизацией» означает «не имеющие рабочей телефонной системы». Это не упрощало жизнь исследователя Нормана Абрамсона (Norman Abramson) и его коллег из Гавайского университета, которые пытались подключить пользователей на удаленных островах к главному компьютеру в Гонолулу. Идея протянуть кабели по дну Тихого океана даже не рассматривалась, так что исследователи искали другое решение.

Найденное решение основывалось на использовании радиосистемы ближнего радиуса действия. Терминал каждого пользователя передавал кадры на центральный компьютер в пределах общей полосы частот. Также присутствовал простой и элегантный метод решения проблемы распределения каналов. Их труды впоследствии стали основой многих исследований (Schwartz, Abramson, 2009). Хотя в работе Абрамсона, получившей название системы ALOHA, использовалась широковещательная радиосвязь со стационарными передатчиками, основная идея применима к любой системе, в которой независимые пользователи соревнуются за право использования одного общего канала.

В данном разделе мы рассмотрим две версии системы ALOHA: чистую и дискретную. Они отличаются тем, непрерывно ли время (чистая версия) или делится на дискретные интервалы, в которые должны помещаться все кадры.

Чистая система ALOHA

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

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

На рис. 4.1 показан пример формирования кадров в системе ALOHA. Все кадры на нашем рисунке имеют один размер, так как при этом пропускная способность системы становится максимальной, именно за счет единого фиксированного размера кадров.

Рис. 4.1. В чистой системе ALOHA кадры передаются в абсолютно произвольное время

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

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

Пусть «время кадра» означает интервал времени, требуемый для передачи стандартного кадра фиксированной длины (то есть длину кадра, деленную на скорость передачи данных). На данный момент мы предполагаем, что новые кадры, порождаемые станциями, хорошо распределены по Пуассону со средним значением N кадров за время кадра. (Допущение о бесконечном количестве пользователей необходимо для того, чтобы гарантировать, что величина N не станет уменьшаться по мере блокирования пользователей.) Если N > 1, это означает, что сообщество пользователей формирует кадры с большей скоростью, чем может быть передано по каналу, и почти каждый кадр будет страдать от столкновений. Мы будем предполагать, что 0 < N <1.

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

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

нала столкновений будет много, а следовательно, G > N. Какая бы ни была нагрузка, производительность канала S будет равна предлагаемой загрузке G, умноженной на вероятность успешной передачи, то есть— вероятность того, что кадр

не пострадает в результате коллизии.

Кадр не пострадает от коллизии в том случае, если в течение интервала времени его передачи не будет послано больше ни одного кадра, как показано на рис. 4.2. При каких условиях затененный кадр будет передан без повреждений? Пусть t — это время, требуемое для передачи кадра. Если какой-либо пользователь сформирует кадр в интервале времени междуто конец этого кадра столкнется с началом

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

Рис. 4.2. Уязвимый период времени для затененного кадра

Вероятность того, что в течение времени кадра, когда ожидается G кадров, будет сформировано k кадров, можно вычислить по формуле распределения Пуассона:

Таким образом, вероятность формирования нуля кадров в течение этого интервала времени равнаСреднее количество кадров, сформированных за интервал времени

длиной в два кадра, равно 2G. Вероятность того, что никто не начнет передачу в течение всего уязвимого периода, равнаУчитывая, чтополучаем:

Зависимость производительности канала от предлагаемого трафика показана на рис. 4.3. Максимальная производительность достигает значениячто приблизительно равно 0,184, приДругими словами, лучшее, на что мы можем на

деяться, — это использовать канал на 18 %. Этот результат несколько разочаровывает, однако в случае, когда каждый передает, когда хочет, трудно ожидать стопроцентного успеха.

Рис. 4.3. Зависимость производительности канала от предлагаемого трафика для систем ALOHA

Дискретная система ALOHA

Вскоре после появления на сцене системы ALOHA Робертс (Roberts, 1972) опубликовал описание метода, позволяющего удвоить производительность систем ALOHA. Его предложение заключалось в разделении времени на дискретные интервалы, называемые слотами (или тактами), соответствующие времени одного кадра. При таком подходе пользователи должны согласиться с определенными временными ограничениями. Одним из способов достижения синхронизации является установка специальной станции, испускающей синхронизирующий сигнал в начале каждого интервала.

В системе Робертса, известной под названием дискретная ALOHA, в отличие от чистой системы ALOHA Абрамсона, станция не может начинать передачу сразу после ввода пользователем строки. Вместо этого она должна дождаться начала нового такта. Таким образом, система ALOHA с непрерывным временем превращается в дискретную. Уязвимый временной интервал теперь становится в два раза короче. Чтобы понять это, взгляните на рис. 4.3 и представьте, какие теперь возможны коллизии. Вероятность отсутствия передачи по каналу за тот же интервал времени, в течение которого передается тестовый кадр, равна. В результате получаем:

Как видно из рис. 4.3, дискретная система ALOHA имеет пик при G = 1. При этом производительность канала составляетчто приблизительно равно 0,368, то

есть в два раза больше, чем в чистой системе ALOHA. Если система работает при условии G = 1, то вероятность появления пустого слота равна 0,368 (из выражения 4.2). Для дискретной системы ALOHA в оптимальной ситуации 37 % интервалов будут пустыми, 37 % — с успешно переданными кадрами и 26 % — со столкнувшимися кадрами. При увеличении количества попыток передачи в единицу времени G количество пустых интервалов уменьшается, но увеличивается количество конфликтных интервалов. Чтобы увидеть, насколько быстро растет количество конфликтных интервалов, рассмотримпередачу тестового кадра. Вероятность того, что он избежит столкновения, равнаФактически это вероятность того, что все остальные станции будут молчать в течение данного тактового интервала. Таким образом, вероятность столкновения равна    Вероятность передачи кадра ровно запопыток (то есть

после k - 1 столкновения, за которыми последует успешная передача) равна:

Ожидаемое число попыток передачи для одной строки, введенной на терминале, равно:

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

Дискретная система ALOHA чрезвычайно важна по одной причине, которая на первый взгляд не кажется очевидной. Она появилась в 1970-х годах, применялась в некоторых экспериментальных системах, затем была почти забыта. Когда был изобретен метод доступа в Интернет по кабельным сетям, вновь возникла проблема распределения единственного канала между большим числом конкурирующих абонентов. Тогда с полок достали запыленные описания дискретной системы ALOHA. Позднее в ситуации, когда несколько тегов RFID пытались общаться с одним считывателем RFID, возник еще один вариант старой проблемы. Дискретная система ALOHA, приправленная несколькими другими идеями, снова сумела спасти ситуацию. Не раз уже было так, что вполне работоспособные протоколы и методы оказывались невостребованными по политическим причинам (например, когда какая-нибудь крупная компания выражала желание, чтобы все на свете использовали исключительно ее продукцию) или из-за постоянно меняющихся технологий. Однако по прошествии многих лет какой-нибудь мудрый человек вспоминал о существовании одного древнего метода, способного решить современную проблему. По этой причине мы изучим в данной главе ряд элегантных протоколов, которые сейчас широко не используются, но запросто могут оказаться востребованными в будущем, — если, конечно, об их существовании будет знать достаточное количество разработчиков сетей. Разумеется, мы изучим и многие протоколы, используемые в настоящее время.

4.2.2. Протоколы множественного доступа с контролем несущей

В дискретной системе ALOHA максимальный коэффициент использования канала, который может быть достигнут, равен 1/e. Такой скромный результат неудивителен, поскольку станции передают данные, когда хотят, не считаясь с тем, что делают остальные станции. В такой системе неизбежно возникает большое количество коллизий. Однако в локальных сетях можно организовать процесс таким образом, что станции будут учитывать поведение друг друга. За счет этого можно достичь значения коэффициента использования канала значительно большего, чем 1/e. В данном разделе мы рассмотрим некоторые протоколы, позволяющие улучшить производительность канала.

Протоколы, в которых станции прослушивают среду передачи данных и действуют в соответствии с этим, называются протоколами с контролем несущей. Было разработано много таких протоколов и их давным-давно подробно проанализировали. Например, см. работу Кляйнрок и Тобаги (Kleinrock, Tobagi, 1975). Ниже мы рассмотрим несколько версий протоколов с контролем несущей.

Настойчивый и ненастойчивый CSMA

Первый протокол с опросом несущей, который мы рассмотрим, называется 1-на-стойчивый протокол CSMA (Carrier-Sense Multiple Access — множественный доступ с контролем несущей). Длинноватое название для простейшей схемы CSMA. Когда у станции появляются данные для передачи, она сначала прослушивает канал, проверяя, свободен он или занят. Если канал бездействует, то станция отправляет данные. В противном случае, когда канал занят, станция ждет, пока он освободится. Затем станция передает кадр. Если происходит столкновение, станция ждет в течение случайного интервала времени, затем снова прослушивает канал и, если он свободен, пытается передать кадр еще раз. Такой протокол называется протоколом CSMA с настойчивостью 1, так как станция передает кадр с вероятностью 1, как только обнаружит, что канал свободен.

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

Если копнуть чуть глубже, то на количество коллизий сильное влияние оказывает задержка распространения сигнала. Существует небольшая вероятность того, что как только станция начнет передачу, другая станция также окажется готовой к передаче и опросит канал. Если сигнал от первой станции еще не успел достичь второй станции, вторая станция решит, что канал свободен, и также начнет передачу, результатом чего будет коллизия. Вероятность зависит от числа кадров, умещающихся в канал, или от показателя «полоса пропускания, умноженная на задержку» для данного канала. Если в канал умещается лишь небольшая часть кадра, как бывает в большинстве локальных сетей, где задержка распространения невелика, то и шанс коллизии мал. Чем больше время распространения сигнала, тем выше вероятность столкновений и ниже производительность протокола.

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

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

Наконец, третий протокол, который мы рассмотрим, это протокол CSMA с настойчивостью р. Он применяется в дискретных каналах и работает следующим образом. Когда станция готова передавать, она опрашивает канал. Если канал свободен, она с вероятностью p начинает передачу. С вероятностью q = 1 - p она отказывается от передачи и ждет начала следующего такта. Этот процесс повторяется до тех пор, пока кадр не будет передан или какая-либо другая станция не начнет передачу. В последнем случае станция ведет себя так же, как в случае столкновения. Она ждет в течение случайного интервала времени, после чего начинает все снова. Если при первом прослушивании канала он оказывается занят, станция ждет следующего интервала времени, после чего применяется тот же алгоритм. В IEEE 802.11 применяется улучшенная версия протокола CSMA с настойчивостью р, которую мы рассмотрим далее.

На рис. 4.4 показана расчетная зависимость производительности канала от предлагаемого потока кадров для всех трех протоколов, а также для чистой и дискретной систем ALOHA.

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

Протокол CSMA с обнаружением коллизий

Настойчивый и ненастойчивый протоколы CSMA, несомненно, являются улучшениями системы ALOHA, поскольку они гарантируют, что никакая станция не начнет передачу, если она определит, что канал уже занят. Однако если две станции, обнаружив, что канал свободен, одновременно начали передачу, столкновение все равно произойдет. Еще одно улучшение — способность станций быстро распознавать коллизию и немедленно прекращать передачу (а не завершать ее), так как данные все равно искажены. Эта стратегия экономит время, и улучшается производительность канала.

Такой протокол, называемый CSMA/CD (Carrier-Sense Multiple Access with Collision Detection — множественный доступ с контролем несущей и обнаружением коллизий), является основой чрезвычайно популярных ЛВС Ethernet, поэтому мы уделим некоторое время более или менее подробному рассмотрению CSMA/CD. Важно понимать, что распознавание коллизий представляет собой аналоговый процесс. Оборудование станции должно «прослушивать» канал во время передачи. Если оно считывает сигнал и понимает, что он отличается от пересылаемого, то сразу понятно — произошла коллизия. Следствие таково, что полученный сигнал не обязательно должен идеально совпадать с отправленным (что может быть сложно в беспроводных сетях — принимаемый сигнал нередко в 1 000 000 раз слабее передаваемого) и что необходимо выбирать такой способ уплотнения, который позволит распознавать коллизии (например, коллизию двух 0-вольтовых сигналов распознать практически невозможно).

В протоколе CSMA/CD, так же как и во многих других протоколах локальных сетей, применяется концептуальная модель, показанная на рис. 4.5. В момент времени t0 одна из станций закончила передачу кадра. Все остальные станции, готовые к передаче, теперь могут попытаться передать свои кадры. Если две станции или более одновременно начнут передачу, то произойдет столкновение. Обнаружив коллизию, станция прекращает передачу, ждет случайный период времени, после чего пытается снова, при условии, что к этому моменту не начала передачу другая станция. Таким образом, наша модель протокола CSMA/CD будет состоять из чередования периодов конкуренции и передачи, а также периодов простоя канала (когда все станции молчат).

Рис. 4.5. Протокол CSMA/CD может находиться в одном из трех состояний: конкуренции,

передачи и простоя

Рассмотрим более подробно алгоритм борьбы за право передачи по каналу. Предположим, две станции одновременно начали передачу в момент времени t0. Сколько

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

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

Рассмотрим следующий сценарий наихудшей ситуации. Пусть время, необходимое для прохождения сигнала между двумя самыми дальними станциями, равно т. В момент времени t0 одна из станций начинает передачу. Через интервал времени т - е, за мгновение до того, как сигнал достигнет самой дальней станции, та станция также начинает передавать. Конечно, почти мгновенно она обнаруживает столкновение и останавливается, но всплеск шума, вызванный столкновением, достигает передающей станции только через интервал времени 2т - е с момента начала передачи. Другими словами, станция не может быть уверена в том, что захватила канал, до тех пор пока не пройдет интервал времени 2т с момента начала передачи.

Понимая это, конкурирование CSMA/CD можно рассматривать как дискретную систему ALOHA с шириной интервала 2т. В коаксиальном кабеле длиной 1 км т = 5 мкс. Различие между CSMA/CD и дискретной системой ALOHA состоит в том, что в первом случае за слотом, в течение которого передачу осуществляет только одна станция (то есть когда канал захвачен), следует передача оставшейся части кадра. Это позволит значительно улучшить производительность, если время кадра будет намного больше времени распространения сигнала по каналу.

4.2.3. Протоколы без столкновений

Хотя в протоколе CSMA/CD столкновения не могут происходить после того, как станция захватывает канал, они могут случаться в период конкуренции. Эти столкновения снижают производительность системы, особенно когда произведение полосы пропускания на значение задержки велико, то есть при большой длине кабеля (и больших т) и коротких кадрах. Коллизии не только уменьшают пропускную способность, они делают время пересылки кадра непостоянным, что очень плохо для трафика, передаваемого в режиме реального времени, такого как голосовые данные по протоколу IP. Метод CSMA/CD оказывается не универсальным.

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

В описываемых ниже протоколах предполагается наличие N станций, у каждой из которых запрограммирован постоянный уникальный адрес в пределах от 0 до N - 1. То что некоторые станции могут часть времени оставаться пассивными, роли не играет.

Также предполагается, что задержка распространения сигнала пренебрежимо мала. Главный вопрос остается неизменным: какой станции будет предоставлен канал после передачи данного кадра? Мы будем по-прежнему использовать модель, изображенную на рис. 4.5, с ее дискретными интервалами конкуренции.

Протокол битовой карты

В первом протоколе без столкновений, который мы рассмотрим, называющемся основным методом битовой карты (basic bit-map method), каждый период конкуренции состоит ровно из N временных интервалов. Если у станции 0 есть кадр для передачи, она передает единичный бит во время 0-го интервала. Другим станциям не разрешается передача в это время. Во время интервала 1 станция 1 также сообщает, есть ли у нее кадр для передачи, передавая бит 1 или 0. В результате к окончанию интервала N все N станций знают, кто хочет передавать. В этот момент они начинают передачу в соответствии со своим порядком номеров (на рис. 4.6 приведен пример для N = 8).

Рис. 4.6. Базовый протокол битовой карты

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

Протоколы, в которых намерение передавать объявляется всем перед самой передачей, называются протоколами с резервированием (reservation protocols), так как

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

При слабой загрузке канала битовая карта просто будет повторяться снова и снова, изредка перемежаясь кадрами. Рассмотрим эту ситуацию с точки зрения станции с небольшим номером, например 0 или 1. Обычно в тот момент, когда у нее возникает потребность в передаче, текущий интервал времени уже находится где-то в середине битовой карты. В среднем станция будет ждать N/2 интервалов до окончания текущего периода резервирования и еще N интервалов следующего (своего) периода резервирования, не считая кадров, передаваемых между двумя этими периодами, прежде чем она сможет начать передачу.

Перспективы станций с большими номерами более радужны. В среднем время ожидания передачи составит половину цикла (N/2 однобитовых интервалов). Станциям

с большими номерами редко приходится ждать следующего цикла. Поскольку станциям с небольшими номерами приходится ждать в среднем 1,5N интервала, а станциям с большими номерами — N/2 интервалов, среднее время ожидания для всех станций составляет N интервалов.

При низкой загрузке канала его производительность легко сосчитать. Накладные расходы на кадр составляют N бит, и при длине кадра в d бит эффективность равна

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

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

Передача маркера

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

В протоколе маркерного кольца (token ring) для определения порядка, в котором станции отправляют данные, используется топология сети. Станции подключены одна к другой, образуя простое кольцо. Таким образом, передача маркера заключается в получении его с одного направления и пересылке в противоположном, как видно на рис. 4.7. Кадры передаются в том же направлении, что и маркер. Они путешествуют по кольцу, проходя по всем станциям, которые оказываются на их пути. Однако для того чтобы кадр не циркулировал вечно (как маркер), какая-то станция должна извлечь его из кольца. Это может быть либо первоначальный отправитель (если кадр прошел полный цикл), либо станция-получатель.

Рис. 4.7. Маркерное кольцо

Обратите внимание, что для реализации передачи маркера физическое кольцо не требуется. Канал, соединяющий станции, может иметь форму одной длинной шины. Станции просто пересылают маркер по шине соседям в предопределенном порядке. Наличие маркера позволяет станции использовать шину для отправки одного кадра, как и раньше. Такой протокол называется маркерной шиной (token bus).

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

Протоколы MAC на базе маркерных колец появляются с определенной периодичностью. Один из ранних протоколов (который назывался Token Ring, то есть «Маркерное кольцо» и стандартизирован в IEEE 802.5) в 1980-е годы был популярен в качестве альтернативы классическому Ethernet. В 1990-е годы намного более быстрое маркерное кольцо под названием FDDI (Fiber Distributed Data Interfaceволоконно-оптический распределенный интерфейс данных) потерпело поражение от коммутируемого Ethernet. В 2000-е маркерное кольцо RPR (Resilient Packet Ringотказоустойчивое пакетное кольцо), определенное в стандарте IEEE 802.17, стандартизирует множество вариантов кольцевых сетей, применяемых в городских условиях поставщиками услуг Интернета. Интересно, что появится после 2010 года.

Двоичный обратный отсчет

Недостатком базового протокола битовой карты, а также протокола с передачей маркера являются накладные расходы в один бит на станцию, из-за чего они плохо масштабируются на большие сети с тысячами станций. Используя двоичный адрес станции, можно улучшить эффективность канала. Станция, желающая занять канал, объявляет свой адрес в виде битовой строки, начиная со старшего бита. Предполагается, что все адреса станций имеют одинаковую длину. Будучи отправленными одновременно, биты адреса в каждой позиции логически складываются (логическое ИЛИ) средствами канала. Мы будем называть этот протокол протоколом с двоичным обратным отсчетом (binary countdown). Он использовался в сети Datakit (Fraser, 1987). Неявно предполагается, что задержки распространения сигнала пренебрежимо малы, поэтому станции слышат утверждаемые номера практически мгновенно.

Во избежание конфликтов следует применить правило арбитража: как только станция с 0 в старшем бите адреса видит, что в суммарном адресе этот 0 заменился единицей, она сдается и ждет следующего цикла. Например, если станции 0010, 0100, 1001 и 1010 конкурируют за канал, то в первом битовом интервале они передают биты 0, 0, 1 и 1 соответственно. В этом случае суммарный первый бит адреса будет равен 1. Следовательно, станции с номерами 0010 и 0100 считаются проигравшими, а станции 1001 и 1010 продолжают борьбу.

Следующий бит у обеих оставшихся станций равен 0 — таким образом, обе продолжают. Третий бит равен 1, поэтому станция 1001 сдается. Победителем оказывается станция 1010, так как ее адрес наибольший. Выиграв торги, она может начать передачу кадра, после чего начнется новый цикл торгов. Схема протокола показана на рис. 4.8. Данный метод предполагает, что приоритет станции напрямую зависит от ее номера. В некоторых случаях такое жесткое правило может играть положительную, в некоторых — отрицательную роль.

Рис. 4.8. Протокол с двоичным обратным отсчетом. Прочерк означает молчание

Эффективность использования канала при этом методе составляет d/(d + log2W). Однако можно так хитро выбрать формат кадра, что его первое поле будет содержать адрес отправителя, тогда даже эти log2W бит не пропадут зря и эффективность составит 100 %.

Двоичный обратный отсчет является примером простого, элегантного и эффективного протокола, который еще предстоит открыть заново разработчикам будущих сетей. Хочется надеяться, что когда-нибудь он займет свою нишу в сетевых технологиях.

4.2.4. Протоколы с ограниченной конкуренцией

Итак, мы рассмотрели две основные стратегии предоставления доступа к каналу в широковещательных сетях: соревнование, как в CSMA, и бесконфликтные протоколы. Каждую стратегию можно оценить по двум важным параметрам: времени задержки при низкой загрузке канала и эффективность канала при большой загрузке. В условиях низкой загрузки конфликты (то есть чистая или дискретная системы ALOHA) предпочтительнее, так как время задержки в таких системах меньше (коллизий меньше). По мере роста загруженности канала системы со столкновениями становятся все менее привлекательными, поскольку возрастают накладные расходы, связанные с конфликтами. Для бесконфликтных протоколов справедливо обратное. При низкой нагрузке у них относительно высокое время задержки, но по мере увеличения нагрузки эффективность использования канала не уменьшается, как у конфликтных протоколов, а наоборот, возрастает (накладные расходы фиксированные).

Очевидно, было бы неплохо объединить лучшие свойства обеих стратегий и получить протокол, использующий разные стратегии при разной загруженности канала. Такие протоколы мы будем называть протоколами с ограниченной конкуренцией (limited-contention protocols). Они в самом деле существуют, и их рассмотрением мы завершим изучение сетей с опросом носителя.

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

Прежде чем приступить к рассмотрению асимметричных протоколов, давайте кратко рассмотрим производительность в симметричном случае. Предположим, что k станций борются за доступ к каналу. Вероятность передачи каждой станции в каждый интервал времени равна р. Вероятность того, что какая-то станция успешно получит доступ к каналу на данный интервал времени, составляется из вероятности того, что любая станция передает данные с вероятностьюр, а все остальные k - 1 станций воздерживаются от передачи, каждая с вероятностью 1 - р. Итоговое значение равно kp(1 - p)k-1. Чтобы найти оптимальное значение вероятности р, продифференцируем данное выражение по р, приравняем результат нулю и решим полученное уравнение относительно р. В результате мы получим, что наилучшее значение р равно 1/k. Заменяя в формуле р на 1/k, получаем вероятность успеха при оптимальном значении р:

Зависимость этой вероятности от количества готовых станций графически показана на рис. 4.9. Для небольшого числа станций значение вероятности успеха является неплохим, однако как только количество станций достигает хотя бы пяти, вероятность снижается почти до асимптотической величины, равной 1/e.

Рис. 4.9. Вероятность получения доступа к каналу в симметричном протоколе

Из рисунка очевидно, что вероятность получения доступа к каналу для какой-либо станции можно увеличить, только снизив конкуренцию за канал. Этим занимаются протоколы с ограниченной конкуренцией. Они сначала делят все станции на группы (необязательно непересекающиеся). Состязаться за интервал 0 разрешается только членам группы 0. Если кто-то из них выигрывает, он получает канал и передает по нему кадр. Если никто из них не хочет передавать или происходит столкновение, члены группы 1 состязаются за интервал 1 и т. д. При соответствующем разбиении на группы конкуренция за каждый интервал времени уменьшается, что увеличивает вероятность его успешного использования (см. левую часть графика).

Вопрос в том, как разбивать станции на группы. Прежде чем обсуждать общий случай, рассмотрим несколько частных случаев. В одном из крайних случаев в каждой группе будет по одной станции. Такое разбиение гарантирует полное отсутствие конфликтов, так как на каждый интервал времени будет претендовать только одна станция. Подобные протоколы уже рассматривались ранее (например, протокол с двоичным обратным отсчетом). Еще одним особым случаем является разбиение на группы, состоящие из двух станций. Вероятность того, что обе станции одновременно начнут передачу в течение одного интервала, равна p2, и при малых значениях p этим значением можно пренебречь. По мере увеличения количества станций в группах, вероятность столкновений будет возрастать, однако длина битовой карты, необходимой, чтобы перенумеровать все группы, будет уменьшаться. Другим предельным случаем будет одна группа, в которую войдут все станции (то есть дискретная система ALOHA). Нам требуется механизм динамического разбиения станций на группы, с небольшим количеством крупных групп при слабой загруженности канала и большом количестве мелких групп (может быть, даже состоящих из одной станции каждая), когда загруженность канала высока.

Протокол адаптивного прохода по дереву

Одним из простых способов динамического разбиения на группы является алгоритм, разработанный во время Второй мировой войны в армии США для проверки солдат на сифилис (Dorfman, 1943). Брался анализ крови у N солдат. Часть каждого образца помещалась в одну общую пробирку. Этот смешанный образец проверялся на наличие антител. Если антитела не обнаруживались, все солдаты в данной группе объявлялись здоровыми. В противном же случае группа делилась пополам, и каждая половина группы проверялась отдельно. Подобный процесс продолжался до тех пор, пока размер группы не уменьшался до одного солдата.

В компьютерной версии данного алгоритма (Capetanakis, 1979) станции рассматриваются в виде листьев двоичного дерева, как показано на рис. 4.10. В первом временном интервале состязания за право передачи участвуют все станции. Если кому-нибудь это удается, то на этом работа алгоритма заканчивается. Если же происходит столкновение, то ко второму этапу состязаний допускается только половина станций, а именно станции, относящиеся к узлу 2 дерева. Если одна из станций успешно захватывает канал, то следующее состязание устраивается для второй половины станций (относящихся к узлу 3 дерева). Если снова происходит конфликт, то к следующему интервалу времени среди состязающихся остается уже четверть станций, относящихся к узлу 4.

Рис. 4.10. Дерево из восьми станций

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

При сильной загруженности канала вряд ли стоит начинать поиск готовой станции с узла 1, поскольку шансов, что всего одна станция из всех будет претендовать на канал, мало. По той же причине могут быть пропущены также узлы 2 и 3. А на каком уровне дерева следует начинать опрос в общем случае? Очевидно, что чем сильнее загруженность канала, тем на более низком уровне дерева должен начинаться поиск готовых станций. Будем предполагать, что каждая станция довольно точно может оценить q (количество готовых на данный момент станций), например, отслеживая недавний трафик.

Пронумеруем уровни дерева на рис. 4.10 — узел 1 на уровне 0, узлы 2 и 3 на уровне 1 и т. д. Обратите внимание на то, что каждый узел на уровне i включает 2-i часть от всех станций. Если q готовых станций распределены равномерно, то ожидаемое их число ниже узла на уровне i равно 2-iq. Интуитивно ясно, что оптимальным уровнем для начала поиска будет тот, на котором среднее число конкурирующих в интервале станций равно 1, то есть уровень, на котором 2-iq = 1. Отсюда i = log2q.

Были разработаны многочисленные усовершенствования базового алгоритма — в частности, некоторые детали обсуждаются у Бертсекаса (Bertsekas) и Галлагера (Gallager) в издании 1992 года. Например, рассмотрим случай, при котором передавать хотят только станции G и H. На узле 1 произойдет конфликт, поэтому будет проверен узел 2. Он окажется пустым. Узел 3 проверять нет смысла, так как там гарантированно будет столкновение. (Нам известно, что под узлом 1 находятся 2 или более станций, а так как под узлом 2 нет ни одной станции, то все они должны быть под узлом 3.) Поэтому проверку узла 3 можно пропустить и сразу проверить узел 6. Поскольку под узлом 6 ничего не оказалось, то проверку узла 7 также можно пропустить и проверить узел G.

4.2.5. Протоколы беспроводных локальных сетей

Систему, состоящую из портативных компьютеров, общающихся по радио, можно рассматривать как беспроводную локальную сеть — мы уже обсуждали это выше. Такая локальная сеть — пример сети на базе широковещательного канала. Ее свойства отличаются от свойств проводных локальных сетей, поэтому здесь требуются специальные протоколы управления доступом к среде (MAC). В данном разделе мы познакомимся с некоторыми из этих протоколов. Далее мы также подробнее поговорим о стандарте 802.11 (WiFi).

Распространенная конфигурация беспроводных локальных сетей подразумевает наличие офисного здания с заранее размещенными в нем точками доступа. Все точки доступа соединены друг с другом медным проводом или оптоволоконным кабелем; они рассылают данные на пользовательские станции. Если мощность передатчиков точек доступа и переносных компьютеров настроена так, что диапазон приема составляет около десятка метров, то соседние комнаты становятся единой сотой, а все здание превращается в большую сотовую систему, подобную традиционной сотовой телефонной системе, описанной в главе 2. В отличие от обычной сотовой системы, у каждой соты в данном случае всего один канал, работающий со всеми станциями, находящимися в нем, включая точку доступа. Обычно пропускная способность такого канала составляет от несколько мегабит в секунду до 600 Мбит/с.

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

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

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

Можно наивно попытаться применить в локальных беспроводных сетях протокол CSMA (Carrier-Sense Multiple Access — множественный доступ с опросом несущей) — просто прослушивать эфир и осуществлять передачу только тогда, когда он никем не занят. Однако проблема заключается в том, что в действительности имеет значение интерференция на приемнике, а не на передатчике, поэтому этот протокол для беспроводных сетей подходит не очень хорошо. Чтобы наглядно увидеть суть проблемы, рассмотрим рис. 4.11, где показаны четыре беспроводные станции. Для нашей

проблемы не имеет значения, какая из них является точкой доступа, а какая — переносной. Мощность передатчиков такова, что взаимодействовать могут только соседние станции, то есть A с B, C с B и D, но не с A.

Рис. 4.11. Беспроводная локальная сеть: аA и C — скрытые станции во время пересылки данных на B; бB и C — засвеченные станции во время пересылки данных на A и D

Сначала рассмотрим, что происходит, когда станции A и C передают данные станции B, как изображено на рис. 4.11, а. Если станция A отправляет данные, а станция C сразу же опрашивает канал, то она не будет слышать станцию A, поскольку та расположена слишком далеко, и может прийти к неверному выводу о том, что канал свободен и что можно посылать данные станции B. Если станция C начнет передавать, она будет конфликтовать со станцией B и исказит кадр, передаваемый станцией A. (Мы предполагаем, что никакая схема по типу CDMA не используется для предоставления нескольких каналов, поэтому из-за коллизий сигналы искажаются и оба кадра разрушаются.) Нам необходим MAC-протокол, который предотвратит такой тип коллизий, ведь это лишняя трата полосы пропускания. Проблема, заключающаяся в том, что одна станция не может слышать возможного конкурента, поскольку конкурент расположен слишком далеко от нее, иногда называется проблемой скрытой станции (hidden terminal problem).

Теперь рассмотрим другую ситуацию: станция B передает данные станции A в то же время, когда станция С хочет начать передачу станции D, как показано на рис. 4.11, б. Станция С при опросе канала слышит выполняемую передачу и может ошибочно предположить, что она не может передавать данные станции D (пунктирная стрелка на рисунке). В действительности такая передача создала бы помехи только в зоне от станции B до станции C, где в данный момент не ведется прием. Нам необходим MAC-протокол, который предотвратит такой тип задержек, ведь это лишняя трата полосы пропускания. Такая ситуация иногда называется проблемой засвеченной станции (exposed terminal problem).

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

Одним из первых значительных протоколов, разработанных для беспроводных локальных сетей и умеющих справляться с этими проблемами, является MACA (Multiple Access with Collision Avoidance множественный доступ с предотвращением коллизий) (Karn, 1990). Идея, лежащая в основе этого протокола, заключается в том, что отправитель заставляет получателя передать короткий кадр, чтобы окружающие станции могли услышать эту передачу и воздержаться от действий на время, требуемое для приема большого информационного кадра. Эта техника заменяет технику прослушивания несущей.

Протокол MACA проиллюстрирован на рис. 4.12. Рассмотрим ситуацию, в которой станция A передает станции B. Станция A начинает с того, что посылает станции кадр RTS (Request To Send запрос на передачу), как показано на рис. 4.12, а. Этот короткий кадр (30 байт) содержит длину кадра данных, который последует за ним. Затем станция B отвечает кадром CTS (Clear To Send разрешение передачи), как показано на рис. 4.12, б. Кадр CTS также содержит длину информационного кадра (скопированную из кадра RTS). Приняв кадр CTS, станция A начинает передачу.

Теперь посмотрим, как реагируют станции, которые слышат передачу одного из этих кадров. Любая станция, которая слышит кадр RTS, находится близко к станции и поэтому должна хранить молчание, пока кадр CTS не будет принят станцией A. Станции, слышащие кадр CTS, находятся вблизи от станции B, следовательно, должны воздержаться от передачи, пока станция B не получит кадр данных, длину которого они могут узнать из кадра CTS.

Рис. 4.12. Протокол MACA: а — станция A посылает кадр RTS станции B; б — станция B отвечает кадром CTS станции A

На рис. 4.12 станция C находится в зоне станции A, но не входит в зону станции B. Поэтому она слышит кадр RTS, передаваемый станцией A, но не слышит кадр CTS, которым отвечает станция B. Поскольку она не интерферирует с кадром CTS, она не обязана воздерживаться от передачи в то время, пока пересылается информационный кадр. Станция D, напротив, находится близко от станции B, но далеко от станции A. Она не слышит кадра RTS, но слышит кадр CTS, а это означает, что она находится вблизи станции, собирающейся принять кадр с данными. Поэтому ей нельзя вести передачу, пока этот кадр не будет передан. Станция E слышит оба управляющих сообщения и так же, как и станция D, должна хранить молчание, пока не будет завершена передача информационного кадра.

Несмотря на все меры предосторожности, конфликты все равно могут произойти. Например, станции B и C могут одновременно послать кадры RTS станции A. При этом кадры столкнутся и не будут приняты. В этом случае передатчики, не услышав кадр CTS в установленный срок, ждут случайное время и после этого повторяют попытку.

4.3. Сеть Ethernet

Итак, мы в целом закончили обсуждение общих вопросов, касающихся протоколов распределения канала. Пришло время перейти к практическим приложениям. Большое число технологий для персональных (PAN), локальных (LAN) и общегородских (MAN) сетей стандартизировано в серии стандартов IEEE 802. Некоторые стандарты выжили, некоторые — нет (см. табл. 1.4). Люди, верящие в реинкарнацию, считают, что одним из членов Ассоциации стандартов IEEE является вновь родившийся Чарльз Дарвин, отбраковывающий слабые технологии. В общем-то, действительно выжили сильнейшие. Наиболее важны стандарты 802.3 (Ethernet) и 802.11 (беспроводные ЛВС). Bluetooth (беспроводные персональные сети) развернуты сегодня очень широко, но их описывают другие стандарты, помимо 802.15. О 802.16 (беспроводные региональные сети) говорить всерьез пока не приходится. Вероятно, им будет посвящен раздел в 6-й редакции этой книги.

Мы начнем исследование реальных систем с Ethernet, вероятно, наиболее распространенном типе компьютерных сетей в мире. Существует два типа Ethernet: классический Ethernet (classic Ethernet), который решает проблему множественного доступа с помощью техник, представленных в этой главе; и коммутируемый Ethernet (switched Ethernet), в котором для соединения компьютеров используются устройства под названием коммутаторы. Важно понимать, что хотя в обоих названиях присутствует слово Ethernet, между этими сетями много различий. Классический Ethernet — это воплощение оригинальной задумки; эти сети работали на скоростях от 3 до 10 Мбит/с. Коммутируемый Ethernet — это более высокий уровень; эти сети работают на скоростях 100, 1000 или 10 000 Мбит/с и носят названия Fast Ethernet («быстрый Ethernet»), Gigabit Ethernet («гигабитный Ethernet») и 10-Gigabit Ethernet («10-гигабитный Ethernet»). Сегодня на практике используется только коммутируемый Ethernet.

Мы обсудим эти исторические формы Ethernet в хронологическом порядке, продемонстрировав развитие сети. Так как Ethernet и IEEE 802.3 — это одно и то же (за исключением двух небольших деталей, которые мы вкратце обсудим), то многие используют оба названия. Мы тоже будем говорить то «Ethernet», то «IEEE 802.3». Дополнительную информацию, касающуюся Ethernet, можно найти в книге (Spurgeon, 2000).

4.3.1. Физический уровень классической сети Ethernet

История Ethernet начинается приблизительно во времена ALOHA, когда студент Боб Меткальф получил магистерскую степень в Массачусетском технологическом университете, а потом сменил место жительство, чтобы защитить докторскую в Гарварде. Во время учебы он познакомился с работой Абрамсона. Она так заинтересовала его, что после выпуска из Гарварда он решил провести лето на Гавайях, работая с Абрамсоном, и только после этого перебираться в исследовательский центр Xerox. Оказавшись в исследовательском центре, он увидел то, что впоследствии должно было стать персональным компьютером. Однако машины были изолированы. Используя свои знания о работе Абрамсона, он, вместе с коллегой Дэвидом Боггсом, создал и реализовал первую локальную сеть (Metcalfe, Boggs, 1976). Для нее использовался длинный толстый коаксиальный кабель, а скорость сети составляла 3 Мбит/с.

Они назвали систему Ethernet в честь люминофорного эфира, через который, как когда-то считалось, распространяются электромагнитные лучи. (Когда в XIX веке британский физик Джеймс Клерк Максвелл обнаружил, что электромагнитное излучение можно описать волновым уравнением, ученые предположили, что пространство должно быть заполнено некой эфирной средой, с помощью которой излучение распространяется. Только после знаменитого эксперимента Майкельсона—Морли, проведенного в 1887 году, физики поняли, что электромагнитное излучение способно распространяться в вакууме.)

Система Xerox Ethernet оказалась настолько успешной, что в 1978 году DEC Intel и Xerox разработали стандарт 10-мегабитного Ethernet, который называется стандартом DIX (DIX standard). С небольшими изменениями в 1983 году стандарт DIX превратился в стандарт IEEE 802.3. К несчастью для Xerox, у этой компании уже к тому моменту была длинная история значительных изобретений (таких как персональный компьютер), которые они не сумели успешно выпустить на рынок (прочитайте об этом в книге «Fumbling the Future», Smith, Alexander, 1988). Когда стало понятно, что у Xerox нет никакой заинтересованности в Ethernet и предложить эта компания может разве что помощь в стандартизации, Меткальф основал собственную компанию, 3Com, и стал продавать адаптеры Ethernet для персональных компьютеров. Были проданы миллионы устройств.

Классический Ethernet — это один длинный кабель, обвивающий здание, к которому подключаются компьютеры. Такая архитектура показана на рис. 4.13. Первый вариант, называемый в народе толстым Ethernet (thick Ethernet), напоминал желтый садовый шланг с маркировкой каждые 2,5 метра — в этих местах подключались компьютеры. (По стандарту 802.3 не требовалось, чтобы кабель был желтым, но это подразумевалось.) Ему на смену пришел тонкий Ethernet (thin Ethernet); эти кабели лучше гнулись, а соединения выполнялись с помощью стандартных разъемов BNC. Тонкий Ethernet был намного дешевле и проще в установке, но длина сегмента не превышала 185 метров (вместо 500 метров для толстого Ethernet), и каждый сегмент поддерживал не более 30 машин (вместо 100).

Все версии Ethernet имеют ограничения по длине кабелей в сегменте, то есть участкам кабелей без использования усилителя. Для построения сетей больших размеров несколько кабелей соединяются повторителями (repeaters). Повторитель — это устройство физического уровня. Он принимает, усиливает (регенерирует) и передает сигналы в обоих направлениях. С точки зрения программного обеспечения, ряд кабелей, соединенных повторителями, не отличается от сплошного кабеля (отличие заключается только во временной задержке, связанной с повторителями).

Рис. 4.13. Архитектура классической сети Ethernet

Информация по этим кабелям передается с использованием манчестерского кода. Сеть Ethernet может состоять из большого количества сегментов кабеля и повторителей, однако два приемопередатчика должны располагаться на расстоянии не более 2,5 км и между ними должно быть не более четырех повторителей. Причина такого ограничения лежит в протоколе MAC, о котором мы поговорим далее.

4.3.2. Протокол подуровня управления доступом к среде в классическом Ethernet

Формат кадра, применяемый для отправки данных, показан на рис. 4.14. Сначала идет поле Preamble (преамбула, заголовок) длиной 8 байт, которое содержит последовательность 10101010 (за исключением последнего байта, в котором значения последних двух битов равны 11). Последний байт в стандарте 802.3 называется разделителем Start of Frame (Начало кадра). Манчестерское кодирование такой последовательности битов дает в результате меандр с частотой 10 МГц и длительностью 6,4 мкс, что позволяет получателю синхронизировать свои часы с часами отправителя. Два последних бита, равных единице, говорят получателю, что сейчас начнется новый кадр.

Затем следуют два адреса: получателя и отправителя. Каждый занимает по 6 байт. Первый передаваемый бит адреса получателя содержит 0 для обычных адресов и 1 для групповых получателей. Групповые адреса позволяют нескольким станциям принимать информацию от одного отправителя. Кадр, отправляемый групповому адресату, может быть получен всеми станциями, входящими в эту группу. Такой механизм называется групповой рассылкой (multicasting). Если адрес состоит только из единиц, то кадр могут принять абсолютно все станции сети. Таким способом осуществляется широковещание (broadcasting). Групповая рассылка более избирательна, но требует некоторых усилий при управлении группами. Широковещание — это более грубая технология, но зато не требует никакой настройки групп.

Рис. 4.14. Форматы кадров: а — DIX Ethernet; б — IEEE 802.3

Интересной особенностью исходных адресов станций является глобальная уникальность. Они централизованно назначаются IEEE, и это гарантирует, что один и тот же глобальный адрес не используется двумя станциями нигде в мире. Идея заключается в том, что каждая станция может быть однозначно идентифицирована по ее 48-битному номеру. Для этого первые 3 байта поля адреса используются для OUI (Organizationally Unique Identifier, организационно уникальный идентификатор). Значения этого поля назначаются IEEE и однозначно определяют производителя. Производителям выделяются блоки по 224 адресов. Производитель назначает последние 3 байта адреса и программирует весь адрес в сетевой карте перед тем, как она поступает в продажу.

Затем следует поле Type или Length, в зависимости от того, относится кадр к стандарту Ethernet или IEEE 802.3. В сетях Ethernet поле Type показывает приемнику, что делать с кадром. Дело в том, что одновременно на одной и той же машине может работать несколько протоколов сетевого уровня, поэтому, когда приходит кадр Ethernet, операционная система должна понимать, какому протоколу его передать. Поле Type определяет процесс, который должен взять себе кадр. Например, код типа 0x0800 означает, что данные содержат пакет IPv4.

Создатели IEEE 802.3 в своей безграничной мудрости решили, что в этом поле должна передаваться длина кадра. Но поскольку для определения длины необходимо заглянуть внутрь данных, то мы наблюдаем нарушение правил использования сетевых уровней. Разумеется, это означало, что получатель никак не мог выяснить, что же ему делать с входящим кадром. Эту проблему решили путем добавления в данные еще одного заголовка для протокола LLC (Logical Link Control, управление логическим каналом). Он занимает 8 байт и передает 2 байта информации о типе протокола.

К сожалению, к моменту опубликования стандарта 802.3 использовалось так много оборудования и программного обеспечения для DIX Ethernet, что лишь немногие про-

изводители и пользователи проявили энтузиазм в отношении переопределения полей Type и Length. В 1997 году IEEE признал поражение и согласился с обоими способами. К счастью, значения всех полей Type, использовавшиеся до 1997 года, были больше 1500 (тогда это значение было установлено в качестве максимального размера поля данных). Теперь правило таково, что любое значение, не превышающее 0x600 (1536), можно интерпретировать как Length, а любое число больше 0x600 — как Type. Теперь IEEE спокойна, что все используют ее стандарт, причем можно продолжать делать то, что программисты делали и до этого, не утруждая себя мыслями о LLC и не чувствуя вины за нарушение стандарта.

Наконец, за полем Type следует поле данных, размер которого ограничен 1500 байт. Такое ограничение было выбрано, в общем-то, произвольно в те времена, когда официально был закреплен стандарт Ethernet. При выборе ссылались на то, что приемопередатчику нужно довольно много оперативной памяти для того, чтобы хранить весь кадр. А память в том далеком 1978 году была еще очень дорогой. Соответственно, увеличение верхней границы размера поля данных привело бы к необходимости установки большего объема памяти, а значит, к удорожанию всего приемопередатчика.

Между тем, кроме верхней границы размера поля данных очень важна и нижняя граница. Поле данных, содержащее 0 байт, вызывает определенные проблемы. Дело в том, что когда приемопередатчик обнаруживает столкновение, он обрезает текущий кадр, а это означает, что отдельные куски кадров постоянно блуждают по кабелю. Чтобы было легче отличить нормальные кадры от мусора, сети Ethernet требуется кадр размером не менее 64 байт (от поля адреса получателя до поля контрольной суммы включительно). Если в кадре содержится меньше 46 байт данных, в него вставляется специальное поле Pad (наполнитель), с помощью которого размер кадра доводится до необходимого минимума.

Другой (и даже более важной) целью установки ограничения размера кадра снизу является предотвращение ситуации, когда станция успевает передать короткий кадр раньше, чем его первый бит дойдет до самого дальнего конца кабеля, где он может столкнуться с другим кадром. Эта ситуация показана на рис. 4.15. В момент времени 0 станция A на одном конце сети посылает кадр. Пусть время прохождения кадра по кабелю равно т. За мгновение до того, как кадр достигнет конца кабеля (то есть в момент времени т - е), самая дальняя станция B начинает передачу. Когда станция B замечает, что получает большую мощность, нежели передает сама, она понимает, что произошло столкновение. Тогда она прекращает передачу и выдает 48-битный шумовой сигнал, предупреждающий остальные станции. Примерно в момент времени 2т отправитель замечает шумовой сигнал и также прекращает передачу. Затем он выжидает случайное время и пытается возобновить передачу.

Если размер кадра будет слишком маленьким, отправитель закончит передачу прежде, чем получит шумовой сигнал. В этом случае он не сможет понять, произошло это столкновение с его кадром или с каким-то другим, и, следовательно, может предположить, что его кадр был успешно принят. Для предотвращения такой ситуации все кадры должны иметь такую длину, чтобы время их передачи было больше 2т. Для локальной сети со скоростью передачи 10 Мбит/с при максимальной длине кабеля в 2500 м и наличии четырех повторителей (требование спецификации 802.3) минимальное время передачи одного кадра должно составлять в худшем случае примерно 50 мкс.

Следовательно, длина кадра должна быть такой, чтобы время передачи было по крайней мере не меньше этого минимума. При скорости 10 Мбит/с на передачу одного бита тратится 100 нс, значит, минимальный размер кадра должен быть равен 500 бит. Из соображений большей надежности это число было увеличено до 512 бит или 64 байт.

Рис. 4.15. Обнаружение столкновения может занять 2т

Последнее поле кадра стандарта Ethernet — Checksum, которое содержит контрольную сумму. По сути дела, это 32-битный код CRC того же типа, как мы обсуждали выше. Он определен как раз при помощи того же порождающего многочлена, что используется для PPP, ADSL и других типов каналов. Этот CRC позволяет обнаруживать ошибки: он проверяет, правильно ли приняты биты кадра. Исправления ошибок нет, и если ошибка обнаруживается, кадр удаляется.

Экспоненциальный двоичный алгоритм выдержки

В классическом Ethernet используется алгоритм CSMA/CD с настойчивостью 1, который мы рассматривали выше. Это означает, что станции прослушивают среду передачи, когда у них появляется кадр на отправку, и отправляют данные, когда среда передачи освобождается. Отправляя кадр, они проверяют, не произошло ли в канале коллизий. Если столкновение случилось, они прерывают передачу, отправляя короткий сигнал о наличии конфликта, и повторяют отправку данных через случайный интервал времени.

Рассмотрим, как определяется случайная длина интервала ожидания после столкновения, так как это новый метод. Модель остается та же, что представлена на рис. 4.5. После возникновения коллизии время делится на дискретные интервалы, длительность которых равна максимальному времени кругового обращения сигнала (то есть его прохождения по кабелю в прямом и обратном направлении), 2т. Для удовлетворения потребностей Ethernet при максимальном размере сети необходимо, чтобы один интервал составлял 512 битовых интервалов или 51,2 мкс.

После первого столкновения каждая станция ждет или 0 или 1 интервал, прежде чем попытаться передавать опять. Если две станции столкнутся и выберут одно и то же псевдослучайное число, то они столкнутся снова. После второго столкновения каждая станция выбирает случайным образом 0, 1, 2 или 3 интервала из набора и ждет опять.

При третьем столкновении (вероятность такого события после двойного столкновения равна 1/4) интервалы будут выбираться в диапазоне от 0 до 23 - 1.

В общем случае, после i столкновений случайный номер выбирается в диапазоне от 0 до 2i - 1, и это количество интервалов станция пропускает. Однако после 10 столкновений подряд интервал рандомизации фиксируется на отметке 1023. После 16 столкновений подряд контроллер признает свое поражение и возвращает компьютеру ошибку. Дальнейшим восстановлением занимаются более высокие уровни.

Этот алгоритм, называемый экспоненциальным двоичным алгоритмом выдержки (binary exponential backoff), был выбран для динамического учета количества станций, пытающихся осуществить передачу. Если выбрать интервал рандомизации равным 1023, то вероятность повторного столкновения будет пренебрежимо мала, однако среднее время ожидания составит сотни тактов, в результате чего среднее время задержки будет слишком велико. С другой стороны, если каждая станция будет выбирать время ожидания всего из двух вариантов, 0 и 1, то в случае столкновения сотни станций они будут продолжать сталкиваться снова и снова до тех пор, пока 99 из них не выберут 1, а одна станция — 0. Такого события можно будет ждать годами. Экспоненциально увеличивая интервал рандомизации по мере возникновения повторных столкновений, алгоритм обеспечивает небольшое время задержки при столкновении небольшого количества станций и одновременно гарантирует, что при столкновении большого числа станций конфликт будет разрешен за разумное время.

Если коллизии не произошло, отправитель предполагает, что кадр, вероятно, был успешно доставлен. Таким образом, ни в CSMA/CD, ни в Ethernet подтверждения не применяются. Такой вариант подходит для кабельных и оптоволоконных каналов с низким числом ошибок. Любые возникающие ошибки распознаются с помощью кода CRC и исправляются более высокими уровнями. Как мы увидим далее, в зашумленных беспроводных каналах подтверждения используются.

4.3.3. Производительность сети Ethernet

Оценим производительность классической сети Ethernet в условиях большой постоянной загрузки, то есть когда k станций постоянно готовы к передаче. Строгий анализ экспоненциального двоичного алгоритма выдержки довольно сложен. Вместо этого мы последуем за рассуждениями Меткальфа (Metcalfe) и Боггса (Boggs) (1976) и предположим, что вероятность повторной передачи в каждом интервале времени постоянна. Если каждая станция передает в течение одного интервала времени с вероятностью р, то вероятность того, что какой-либо станции удастся завладеть каналом, равна

Значение A будет максимальным, когда р = 1/k. При k, стремящемся к бесконечности, A будет стремиться к 1/e. Вероятность того, что период соревнования за канал будет состоять ровно из j интервалов, будет равна A(1 - A) j-1, следовательно, среднее число интервалов борьбы за канал будет равно

Так как длительность каждого интервала времени равна 2т, средняя продолжительность периода борьбы будет составлять w = 2т/А При оптимальном значении вероятности p среднее количество интервалов за период борьбы никогда не будет превосходить е, таким образом, средняя продолжительность периода борьбы будет равна 2те « 5,4т.

Если среднее время передачи кадра составляет P с, то эффективность канала при его сильной загруженности будет равна:

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

Полезно переформулировать выражение (4.6) в терминах длины кадра F, пропускной способности сети B, длины кабеля L и скорости распространения сигнала c для оптимального случая: e интервалов столкновений на кадр. При P = F/B выражение (4.6) примет вид:

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

На рис. 4.16 показана зависимость эффективности канала от числа готовых станций для 2т = 51,2 мкс и скорости передачи данных, равной 10 Мбит/с. Для расчетов используется выражение (4.7). При 64-байтном временном интервале 64-байтные кадры оказываются неэффективными, и это неудивительно. С другой стороны, если использовать кадры длиной 1024 байта, то при асимптотическом значении е периода состязания за канал, равном 64-байтовому интервалу, то есть 174 байтам, эффективность канала составит 85 %. Это намного лучший результат, чем 37 % в системе ALOHA с дискретными интервалами.

Следует отметить, что теоретическому анализу производительности сетей Ethernet (и других сетей) было посвящено много работ. Большинство результатов следует воспринимать с долей (или, лучше, с тонной) скептицизма по двум причинам. Во-первых, практически во всех этих теоретических исследованиях предполагается, что трафик подчиняется пуассоновскому распределению. Когда же исследователи рассмотрели реальные потоки данных, то обнаружилось, что сетевой трафик редко распределен по Пуассону, а чаще включает множество пиков (Paxson and Floyd, 1994; Leland и др., 1994). Это означает, что при увеличении периода усреднения трафик не сглаживается.

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

Число станций, пытающихся передавать

Рис. 4.16. Эффективность сетей стандарта 802.3 на скорости 10 Мбит/с с 512-битовыми интервалами времени

4.3.4. Коммутируемые сети Ethernet

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

Рис. 4.17. Конфигурация Ethernet: а — концентратор; б — коммутатор

Для соединения использовалась витая пара, проложенная телефонной компанией, так как большинство офисных зданий и так было хорошо охвачено кабелем, а пустых пар было достаточно. Такой вариант использования был весьма выгодным, но он ограничивал максимальную длину кабеля между компьютером и концентратором до 100 м (или 200 при условии качественной витой пары категории 5). В подобной конфигурации было легко удалять и добавлять станции, также несложно было находить разрывы кабеля. Благодаря преимуществам использования существующей кабельной разводки и простоте обслуживания концентраторы на витой паре вскоре стали ведущей формой реализации сетей Ethernet.

Однако концентраторы не увеличивают емкость, так как логически они эквивалентны одному длинному кабелю классической сети Ethernet. При добавлении станций доля каждой из них в общей фиксированной емкости канала уменьшается. Наконец, локальная сеть насытится. Одним из решений в данном случае является увеличение скорости передачи данных — например, переход с 10 на 100 Мбит/с, 1 Гбит/с или даже больше. Однако доля мультимедийных данных мощных серверов в общем потоке становится все заметнее, и даже гигабитные версии Ethernet могут перестать справляться со своей задачей.

К счастью, возможно не столь радикальное решение, а именно коммутируемая локальная сеть Ethernet. Сердцем системы является коммутатор (switch), содержащий высокоскоростную плату, объединяющие все порты (см. рис. 4.17, б). Снаружи коммутатор ничем не отличается от концентратора. Это обычные коробки, оборудованные несколькими (от 4 до 48) стандартными разъемами RJ-45 для подключения витой пары. Каждый кабель соединяет коммутатор или концентратор с одним компьютером, как показано на рис. 4.18. У коммутатора есть все преимущества концентратора. Новую станцию легко добавить или удалить, подключив или отключив один провод. Большинство сбоев кабеля или портов легко обнаруживаются по неправильной работе всего лишь одной станции. Общий компонент все же может подвести систему — речь идет о самом коммутаторе, — но если сеть пропадет на всех станциях, инженеры сразу поймут, в чем дело, и заменят устройство.

Рис. 4.18. Коммутатор Ethernet

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

Что произойдет, если две машины или два порта одновременно станут передавать кадры? И снова поведение коммутаторов отличается от концентраторов. Внутри концентратора все станции находятся в одном и том же пространстве столкновений (collision domain). Для планирования пересылки кадров им необходимо применять алгоритм CSMA/CD. У коммутатора каждый порт находится в своем пространстве столкновений. В распространенном случае, когда передача по кабелю осуществляется в дуплексном режиме, и станция, и порт могут одновременно посылать кадры, не беспокоясь о других станциях и портах. Столкновения невозможны, и CSMA/CD не требуется. Однако если кабель полудуплексный, то станция и порт должны договариваться о передачи, применяя CSMA/CD обычным способом.

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

Изменения в технологии портов, на которые пересылаются кадры, также дают преимущества, связанные с безопасностью. Большинство интерфейсов локальных сетей (сетевых адаптеров) работают в «неразборчивом режиме» (promiscuous mode), когда все кадры передаются на все компьютеры, а не только адресату. Если применяется концентратор, то каждый подключенный к нему компьютер может видеть трафик, пересылаемый между всеми остальными компьютерами. Шпионы и сплетники очень любят эту особенность. Коммутатор передает трафик только на порты адресатов. Такое ограничение обеспечивает лучшую изоляцию: трафик не «сбегает» и не попадает в нечистые руки. Однако если вопрос безопасности стоит в вашей организации очень серьезно, в дополнение к этому лучше шифровать трафик.

Так как коммутатор ожидает на каждом входном порту кадры Ethernet, можно использовать некоторые из этих портов в качестве концентраторов. На рис. 4.18 порт в правом верхнем углу соединен не с одной станцией, а с 12-портовым концентратором. Прибывая в концентратор, кадры состязаются самым обычным образом, включая столкновения и двоичную выдержку. Удачливые кадры попадают в коммутатор через концентратор и подвергаются там той же процедуре, что и все остальные входящие кадры. Коммутатор не знает о том, что им пришлось с боем прорываться к нему. Оказавшись в коммутаторе, они перенаправляются на нужные выходные линии через высокоскоростную объединяющую плату. Также возможно, что адресатом была одна из линий, подключенных к концентратору; это означает, что кадр уже был доставлен, так что коммутатор просто удаляет его. Концентраторы проще и дешевле коммутаторов, но из-за стремительного удешевления последних они находятся под угрозой исчезновения. В современных сетях в основном применяется коммутируемый Ethernet. Тем не менее все еще существуют действующие концентраторы.

4.3.5. Fast Ethernet

Примерно тогда же, когда коммутаторы набирали популярность, скорость Ethernet 10 Мбит/с перестала казаться чем-то из ряда вон выходящим. Когда-то казалось, что 10 Мбит/с — это просто фантастически высокая скорость. Примерно так же воспринимали пользователи телефонных модемов появление кабельных модемов. Однако мир меняется очень быстро. В качестве одного из следствий закона Паркинсона («Работа занимает все отведенное на нее время») можно привести следующее правило: «Данные занимают всю предоставленную пропускную способность канала».

Многим приложениям требовалась высокая пропускная способность, и поэтому появились 10-Мбитные ЛВС, связанные лабиринтами повторителей, концентраторов и коммутаторов. Сетевым администраторам иногда казалось, что система держится еле-еле и может развалиться от любого прикосновения. Но даже с коммутаторами Ethernet максимальная полоса пропускания одного компьютера ограничивалась кабелем, которым тот соединялся с портом коммутатора.

Вот при таких обстоятельствах институт IEEE начал в 1992 году пересмотр стандартов и дал заказ комитету 802.3 выработать спецификацию более быстрых сетей. Одно из предложений состояло в том, чтобы сохранить 802.3 без изменений и просто увеличить скорость работы. Другое заключалось в том, чтобы полностью его переделать, снабдить новым набором функций — например, обеспечить возможность передачи данных реального времени, оцифрованной речи. При этом предлагалось сохранить старое название стандарта (такой коммерческий прием). После некоторых колебаний комитет решил все-таки изменить лишь скорость работы 802.3, а все остальные параметры оставить прежними. Такая стратегия позволила бы добиться желаемого прежде, чем технология изменится, и избежать непредвиденных проблем с совершенно новыми разработками. Также обеспечивалась бы обратная совместимость с существующими локальными сетями Ethernet. Сторонники отвергнутого предложения поступили так, как в этой ситуации поступил бы любой человек, связанный с компьютерной индустрией: они хлопнули дверью, организовали собственный комитет и разработали свой стандарт (собственно, 802.12), который, впрочем, с треском провалился.

Работа шла довольно быстро (по меркам комитета стандартизации), и уже в июне 1995 года официально объявили о создании стандарта 802.3u. С технической точки зрения, в нем нет ничего нового по сравнению с предыдущей версией. Честнее было бы назвать это не новым стандартом, а расширением 802.3 (чтобы еще больше подчеркнуть обратную совместимость с ним). Такая стратегия часто используется. Поскольку жаргонное название «Fast Ethernet» (быстрый Ethernet) используется уже практически всеми, то и мы будем следовать этой моде.

Основная идея Fast Ethernet довольно проста: оставить без изменений все старые форматы кадров, интерфейсы, процедуры и лишь уменьшить время передачи одного бита с 100 до 10 нс. Как это технически осуществить? Можно скопировать принцип, применяемый в классическом 10-мегабитном Ethernet, но в 10 раз уменьшить максимальную длину сегмента. Однако преимущества витой пары были столь неоспоримы, что практически все системы типа «Fast Ethernet» в результате были построены именно на этом типе кабеля. Таким образом, в Fast Ethernet используются исключительно концентраторы (хабы) и коммутаторы; никаких моноканалов с ответвителями типа «зуб вампира» или с BNC-коннекторами здесь нет.

Однако некоторые технические решения все же необходимо было принять. Самый важный вопрос заключался в том, какие типы кабелей поддерживать. Одним из претендентов была витая пара категории 3. Основным аргументом в его пользу было то, что практически все западные офисы уже были оборудованы по крайней мере четырьмя витыми парами категории 3 (а то и лучше): они использовались в телефонных линиях и их длина (до ближайшего телефонного щита) составляла не более 100 м. Иногда можно было встретить два таких кабеля. Таким образом, можно было установить в организациях Fast Ethernet, и для этого не требовалось перекладывать кабель во всем здании. Это было очень существенно для многих.

Было во всем этом лишь одно неудобство: витые пары третьей категории не способны передавать сигналы 100-мегабитной сети на расстояние 100 метров (именно таково максимальное расстояние между компьютером и концентратором, установленное стандартом для 10-мегабитных концентраторов). Витые пары категории 5 с такой задачей справились бы без всяких проблем, а для оптоволокна это и вовсе смешная цифра. Надо было найти какой-то компромисс. Не мудрствуя лукаво, комитет 802.3 разрешил применять все три типа кабелей, как показано в табл. 4.2, с условием, что решения на основе витой пары третьей категории будут чуть живее и смогут обеспечить необходимую емкость канала.

Таблица 4.2. Основные типы кабелей для сетей Fast Ethernet

Название

Тип

Длина сегмента, м

Преимущества

100Base-T4

Витая пара

100

Использование неэкранированной витой пары категории 3

100Base-TX

Витая пара

100

Полный дуплекс при 100 Мбит/с (витая пара 5 категории)

100Base-FX

Оптоволокно

2000

Полный дуплекс при 100 Мбит/с; большая длина сегмента

В схеме 100Base-4T, использующей витую пару категории 3, сигнальная скорость составляет 25 МГц, что лишь на 25 % больше, чем 20 МГц стандарта Ethernet (помните, что в Манчестерском кодировании, которое обсуждается выше, требуется удвоенная частота). Чтобы достичь требуемой пропускной способности, в схеме 100Base-4T применяются четыре витые пары. Из четырех витых пар одна всегда направляется на концентратор, одна — от концентратора, а две оставшиеся переключаются в зависимости от текущего направления передачи данных. Для достижения скорости 100 Мбит/с в направлении передачи на каждой из витых пар применяется довольно сложная схема с отправкой троичных цифровых сигналов с тремя разными уровнями напряжения. Вряд ли эта схема выиграет приз за элегантность, так что детали мы опустим. Однако так как в стандартной телефонной проводке десятилетиями использовались четыре витые пары в каждом кабеле, в большинстве офисов можно применять уже проложенные кабели. Разумеется, для этого придется отказаться от офисного телефона, но не такая уж это большая цена за быструю электронную почту.

Система 100Base-T4 не дошла до финала, поскольку во многих офисных зданиях проложили витую пару пятой категории для сетей 100Base-TX, которые в итоге завоевали рынок. Такая схема проще, так как кабели этого типа могут работать с сигналами на частоте 125 МГц. Поэтому для каждой станции используются только две витые пары: одна к концентратору, другая от него. Не применяется ни прямое битовое кодирование (то есть NRZ), ни Манчестерский код. Вместо них имеется специальная система кодирования, называемая 4B/5B (подробнее об этом выше). Четыре бита данных кодируются в форме пяти сигнальных бит и отправляются на частоте 125 МГц, обеспечивая скорость 100 Мбит/с. Это простая схема, но в ней выполняется достаточное число переходов для обеспечения синхронизации, и полоса пропускания расходуется довольно эффективно. Система 100Base-TX является полнодуплексной, станции могут передавать на скорости 100 Мбит/с по одной витой паре и одновременно принимать на той же скорости по другой.

Последний вариант, 100Base-FX, использует два оптических многомодовых кабеля, по одному для передачи в каждом направлении, то есть также полный дуплекс на скорости 100 Мбит/с в каждом направлении. В таком варианте расстояние между станцией и коммутатором может достигать 2 км.

Fast Ethernet поддерживает соединение с помощью либо концентраторов, либо коммутаторов. Для того чтобы алгоритм CSMA/CD работал, необходимо соблюдать соотношение между минимальным размером кадра и максимальной длиной кабеля, учитывая возрастание скорости от 10 до 100 Мбит/с. Таким образом, либо нужно увеличить минимальный размер кадра (сделать его больше 64 байт), либо пропорционально уменьшить максимальную длину кабеля (менее 2500 м). Самый простой способ оказался следующим: уменьшить максимальное расстояние между двумя станциями в 10 раз, так как концентратор со стометровыми кабелями точно не будет выходить за новые границы. Однако кабели 100Base-FX в 2 км слишком длинны для 100-мегабитного концентратора с обычным алгоритмом управления коллизиями в сетях Ethernet. Эти кабели нужно подключать к коммутатору, чтобы они могли работать в полнодуплексном режиме без коллизий.

Пользователям очень полюбился Fast Ethernet, но они не собирались так просто выбрасывать 10-Мбитные платы Ethernet со старых компьютеров. В результате практически все коммутаторы могут поддерживать и 10-Мбитные, и 100-Мбитные станции. Для упрощения обновлений сам стандарт предусматривает механизм под названием автоматическое согласование (autonegotiation), который позволяет двум станциям автоматически договориться об оптимальной скорости (10 или 100 Мбит) и дуплексном режиме (полный дуплекс или полудуплекс). Обычно он работает без проблем, однако известны случаи возникновения проблем несовпадения дуплексного режима.

Одна станция применяет автоматическое согласование, а на другой оно не работает, и сразу же устанавливается полнодуплексный режим (Shalunov, Carlson, 2005). Большая часть аппаратуры Ethernet использует эту функцию для самонастройки.

4.3.6. Gigabit Ethernet

Не успели еще, как говорится, высохнуть чернила на только что созданном стандарте Fast Ethernet, как комитет 802 приступил к работе над новой версией. Ее почти сразу окрестили Gigabit Ethernet (гигабитной сетью Ethernet). IEEE ратифицировал наиболее популярную форму сети в 1999 году под названием 802.3ab. Ниже мы обсудим некоторые ключевые свойства Gigabit Ethernet. Более подробную информацию можно найти в(Spurgeon, 2000).

Главные предпосылки комитета в отношении Gigabit Ethernet были те же самые, что и для Fast Ethernet: увеличить производительность в 10 раз, сохранив обратную совместимость со старыми сетями Ethernet. В частности, Gigabit Ethernet должен был обеспечить дейтаграммный сервис без подтверждений, как при одноадресной, так и при широковещательной передаче. При этом необходимо было сохранить неизменными 48-битную схему адресации и формат кадра, включая нижние и верхние ограничения его размера. Новый стандарт удовлетворил всем этим требованиям.

Как и Fast Ethernet, все конфигурации Gigabit Ethernet строятся по принципу «точка-точка». Простейшая гигабитная сеть, показанная на рис. 4.19, а, состоит из двух компьютеров, напрямую соединенных друг с другом. В более общем случае, однако, имеется коммутатор или концентратор, к которому подсоединяется множество компьютеров, возможна также установка дополнительных коммутаторов или концентраторов (рис. 4.19, б). Но в любом случае, к одному кабелю Gigabit Ethernet всегда присоединяются два устройства, ни больше, ни меньше.

Рис. 4.19. Сеть Ethernet, состоящая: а — из двух станций; б — из множества станций

Аналогично, как и Fast Ethernet, Gigabit Ethernet может работать в двух режимах: полнодуплексном и полудуплексном. «Нормальным» считается полнодуплексный, при этом трафик может идти одновременно в обоих направлениях. Этот режим используется, когда имеется центральный коммутатор, соединенный с периферийными компьютерами или коммутаторами. В такой конфигурации сигналы всех линий буферизируются, поэтому абоненты могут отправлять данные, когда им вздумается. Отправитель не прослушивает канал, потому что ему не с кем конкурировать. На линии между компьютером и коммутатором компьютер — это единственный потенциальный отправитель; передача произойдет успешно даже в том случае, если одновременно с ней ведется передача со стороны коммутатора (линия полнодуплексная). Так как конкуренции в данном случае нет, протокол CSMA/CD не применяется, поэтому максимальная длина кабеля определяется исключительно мощностью сигнала, а вопросы времени распространения шумового всплеска здесь не встают. Коммутаторы могут работать на смешанных скоростях; более того, они автоматически выбирают оптимальную скорость. Самонастройка поддерживается так же, как и в Fast Ethernet, но теперь можно выбирать скорость 10, 100 или 1000 Мбит/с.

Полудуплексный режим работы используется тогда, когда компьютеры соединены не с коммутатором, а с концентратором. Концентратор не буферизирует входящие кадры. Вместо этого он электрически соединяет все линии, симулируя моноканал обычного Ethernet. В этом режиме возможны коллизии, поэтому применяется CSMA/ CD. Поскольку кадр минимального размера (то есть из 64 байт) может передаваться в 100 раз быстрее, чем в классической сети Ethernet, максимальная длина кабеля должна быть, соответственно, уменьшена в 100 раз. Она составляет 25 м — именно при таком расстоянии между станциями шумовой всплеск гарантированно достигнет отправителя до окончания его передачи. Если бы кабель имел длину 2500 м, то отправитель кадра из 64 байт при 1 Гбит/с успел бы много чего наделать даже за то время, пока его кадр прошел бы только десятую часть пути в одну сторону, не говоря уж о том, что сигнал должен еще и вернуться обратно.

Ограничение на длину было таким жестким, что комитет решил добавить в стандарт два новых свойства, позволивших увеличить максимальную длину кабеля до 200 м, что, вероятно, должно удовлетворить большинство организаций. Первое называется расширением носителя (carrier extension). Заключается это расширение всего-навсего в том, что аппаратура вставляет собственное поле заполнения, растягивающее нормальный кадр до 512 байт. Поскольку это поле добавляется отправителем и изымается получателем, то программному обеспечению нет до него никакого дела. Конечно, тратить 512 байт на передачу 64 байт — это несколько расточительно с точки зрения эффективности использования пропускной способности. Эффективность такой передачи составляет всего 9 %.

Второе свойство, позволяющее увеличить допустимую длину сегмента, — это пакетная передача кадров (frame bursting). Это означает, что отправитель может посылать не единичный кадр, а пакет, объединяющий в себе сразу много кадров. Если полная длина пакета оказывается менее 512 байт, то, как в предыдущем случае, производится аппаратное заполнение фиктивными данными. Если же кадров, ждущих передачу, хватает на то, чтобы заполнить такой большой пакет, то работа системы оказывается очень эффективной. Такая схема, разумеется, предпочтительнее расширения носителя.

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

и коммутаторы Gigabit Ethernet когда-то были довольно дороги, но когда спрос на них возрос, цены существенно упали. Однако обратная совместимость — это нечто священное в компьютерной индустрии, поэтому, несмотря ни на что, комитету необходимо было это учесть. Сегодня большинство компьютеров поставляются с интерфейсом Ethernet, поддерживающим работу на скоростях 10, 100 и 1000 Мбит/с и совместимым с любыми из них.

Gigabit Ethernet поддерживает как медные, так и волоконно-оптические кабели, что отражено в табл. 4.3. Работа на скорости около 1 Гбит/с означает необходимость кодирования и отправки бита каждую наносекунду. Первоначально этого достигали за счет коротких экранированных медных кабелей (версия 1000Base-CX) и оптоволокна. Волоконная оптика допускает две длины волны, и, следовательно, существуют две разные версии: 0,85 мкм (короткие волны, для 1000Base-SX) и 1,3 мкм (длинные, для 1000Base-LX).

Таблица 4.3. Кабели Gigabit Ethernet

Название

Тип

Длина сегмента,

м Преимущества

1000Base-SX

Оптоволокно

550

Многомодовое волокно (50, 62,5 мкм)

1000Base-LX

Оптоволокно

5000

Одномодовое (10 мкм) или многомодовое (50, 62,5 мкм) волокно

1000Base-CX

2 экранированные витые пары

25

Экранированная витая пара

1000Base-T

4 неэкранированные витые пары

100

Стандартная витая пара 5-й категории

Передача сигналов с помощью коротких волн возможна с дешевыми светодиодами. Такой вариант применяется с многомодовым волокном для соединения станций внутри здания, так как для 50-мкм волокна допустимая длина — не более 500 м. Передача сигналов на длинных волнах требует более дорогих лазеров. С другой стороны, в сочетании с одномодовым (10 мкм) волокном разрешается длина кабеля до 5 км. Это означает возможность подключения друг к другу зданий, например, в студенческом городке, аналогично связям «точка-точка». Более поздние вариации стандарта допускали даже более длинные связи на одномодовом волокне.

Для отправки бит по этим версиям соединений Gigabit Ethernet из другой сетевой технологии под названием Fibre Channel (оптоволоконный канал) была заимствована система кодирования 8B/10B, о которой говорилось выше. В этой системе 8 бит данных кодируются в кодовые слова из 10 бит, которые отправляются по проводу или оптическому волокну — отсюда и название 8B/10B. Кодовые слова выбираются так, чтобы они могли быть сбалансированы (например, имеющие равное число нулей и единиц) и чтобы переход осуществлялся достаточное число раз для восстановления синхронизации. Отправка NRZ закодированных бит требует лишь на 25 % большей полосы пропускания, чем для незакодированных бит, — значительное улучшение по сравнению со стопроцентным увеличением для Манчестерского кода.

Однако все это требовало новых медных или оптоволоконных кабелей, поддерживающих более быструю передачу сигналов. Ни один из них не опирается на огромное количество витой пары пятой категории, которая была проложена для сетей Fast Ethernet. В течение года потребность была заполнена благодаря 1000Base-T, и с тех пор это остается наиболее популярной формой Gigabit Ethernet. Очевидно, людям не очень нравится заново прокладывать кабели в своих зданиях.

Для того чтобы сеть Ethernet могла работать на проводах пятой категории со скоростью 1000 Мбит/с, требуется более сложная схема передачи сигналов. Во-первых, используются все четыре витые пары в кабеле; каждая пересылает данные одновременно в обоих направлениях, применяя цифровую обработку сигналов для их разделения. Для обеспечения скорости 125 Мсимволов/с в каждом проводе применяется пять уровней напряжения, которые переносят по 2 бита. Схема создания символов из бит не так проста. Она включает шифрование (для безопасной передачи) и код исправления ошибок, в котором четыре значения внедряются в пять сигнальных уровней.

1 Гбит/с — это довольно много. Например, если приемник отвлечется на какое-то дело в течение 1 мс и при этом забудет или не успеет освободить буфер, это означает, что он проспит примерно 1953 кадра. Может быть и другая ситуация: один компьютер выдает данные по гигабитной сети, а другой принимает их по классическому Ethernet. Вероятно, первый быстро завалит данными второго. В первую очередь, переполнится буфер обмена. Исходя из этого, было принято решение о внедрении в систему Gigabit Ethernet контроля потока. Для реализации контроля потока одна из сторон посылает служебный кадр, сообщающий о том, что второй стороне необходимо приостановиться на некоторое время. Служебные кадры PAUSE — это, на самом деле, обычные кадры Ethernet, в поле Type которых записано 0х8808. Продолжительность паузы определяется в единицах времени передачи минимального кадра. Для Gigabit Ethernet такая единица равна 512 нс, а паузы могут длиться до 33,6 мс.

Вместе с Gigabit Ethernet было добавлено и еще одно расширение. Джамбо-па-кеты (Jumbo frames) допускают кадры длиной более 1500 байт, обычно до 9 Кбайт. Это расширение защищено патентом. Оно не определяется в стандарте, потому что в противном случае Ethernet уже не будет совместим с предыдущими версиями. Тем не менее большинство производителей его все же поддерживают. Обоснование таково, что 1500 байт — это слишком маленькая единица информации на гигабитных скоростях. Манипулируя большими блоками информации, можно уменьшить частоту пересылки кадров и снизить нагрузку из-за необходимой обработки (например, не придется прерывать процессор, чтобы сообщить о прибытии кадра, или разбивать и заново соединять сообщения, не поместившиеся в одном кадре Ethernet).

4.3.7. 10-гигабитный Ethernet

Gigbit Ethernet был стандартизован, и комитет 802 заскучал. Тогда IEEE предложил ему начать работу над 10-Gigbit Ethernet (10-гигабитным Ethernet). Работа шла по тому же принципу, что и раньше, при стандартизации предыдущих версий Ethernet. Первые стандарты для оптоволоконного и экранированного медного кабеля появились в 2002 и 2004 годах, а стандарт для медной витой пары последовал в 2006 году.

10 Гбит/с — это поистине колоссальная скорость. В 1000 раз быстрее первоначального стандарта Ethernet! Где она может понадобиться? Ответ скрывается в дата-центрах и точках обмена трафиком с высококлассными маршрутизаторами, коммутаторами и серверами, а также в сильно загруженных магистральных каналах, соединяющих офисы компаний в разных городах. Весь город можно охватить единой сетью на базе оптоволокна и Ethernet. Такие длинные связи используют оптическое волокно, тогда как более короткие связи можно выполнять с помощью медных кабелей.

Все версии 10-Gigbit Ethernet поддерживают только полнодуплексную передачу данных. CSMA/CD больше не является частью архитектуры, и стандарты фокусируются на деталях физического уровня, которые обеспечивают такую высокую скорость. Однако совместимость не потеряла своего значения, поэтому интерфейсы 10-Gigabit Ethernet выполняют автоматическое согласование скорости и выбирают максимально возможное значение для обоих концов линии.

Основные типы 10-Gigbit Ethernet перечислены в табл. 4.4. На средних расстояниях применяется многомодовое волокно с длиной волны 0,85 мкм, а на больших расстояниях — одномодовое волокно с длиной волны 1,3 и 1,5 мкм. Сеть 10GBase-ER может охватывать до 40 км, что хорошо подходит для глобальных приложений. Все эти версии отправляют последовательный поток информации, которая получается путем смешивания бит данных и кодирования 64B/66B. Такое кодирование требует меньше накладных расходов, чем 8B/10B.

Таблица 4.4. Кабели 10-Gigbit Ethernet

Версия, определенная первой, 10GBase-CX4, работает на базе кабелей с четырьмя парами биаксиального медного провода. В каждой паре используется кодирование 8B/10B, они работают на скорости 3,125 Гсимволов/с, обеспечивая скорость передачи данных 10 Гбит/с. Эта версия дешевле волоконной и первой вышла на рынок, однако еще непонятно, сумеет ли она вытеснить с рынка 10-Gigbit Ethernet на базе витой пары.

10GBase-T — это версия, работающая на неэкранированной витой паре. Несмотря на то что официально она требует прокладки кабеля категории 6а, пока что можно использовать и более старые категории (включая пятую), то есть уже проложенные во множестве зданий по всему миру кабели. Неудивительно, что для достижения скорости 10 Гбит/с на витой паре огромные старания приходится приложить физическому уровню. Мы взглянем только на самые общие особенности. Каждая из четырех витых пар используется для пересылки данных в обоих направлениях на скорости 2500 Мбит/с. Это достигается за счет скорости пересылки сигналов 800 Мсимволов/с на 16 уровнях напряжения. Символы создаются путем перемешивания данных, применения кода LDPC (Low Density Parity Check) и последующего кодирования для исправления ошибок.

Различные варианты 10-Gigbit Ethernet еще не поделили рынок, а комитет 802.3 уже идет дальше. В конце 2007 года IEEE создала группу по стандартизации сетей Ethernet, работающих на скоростях 40 и 100 Гбит/с. Такой рывок позволит Ethernet стать серьезным соперником альтернативным технологиям в таких областях, требующих высокой производительности, как междугородные соединения в магистральных сетях и короткие соединения по системным платам устройств. Описание стандарта еще не завершено, однако определенные патентованные продукты уже доступны.

4.3.8. Ретроспектива Ethernet

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

Возможно, основной причиной столь длительного успеха является простота и гибкость системы. Простота в данном случае означает, прежде всего, надежность, невысокую цену и легкость обслуживания. С тех пор как признание получили архитектуры на базе концентраторов и коммутаторов, чисто технические поломки стали чрезвычайно редки. Человек так устроен, что он с трудом может отказаться от чего-либо, что хорошо работает, в пользу чего-то другого. Нужно принять во внимание и тот факт, что огромное количество кое-как собранной компьютерной аппаратуры работает не слишком надежно. Именно по этой причине так называемые «апгрейды» часто дают результат, ровно противоположный ожидаемому. Бывает так, что системы после них работают не лучше, а даже хуже.

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

Сети Ethernet не доставляют большой головной боли системным администраторам — они обслуживаются без особых проблем. Не нужно устанавливать никакое программное обеспечение (кроме драйверов), и очень мало конфигурационных таблиц (в которых так просто ошибиться). Новые узлы добавляются очень просто.

Еще одно достоинство Ethernet заключается в хорошем взаимодействии с TCP/ IP — доминирующим протоколом сети Интернет. IP — это протокол без установления соединения, поэтому он без проблем внедряется в локальных сетях Ethernet, которые также используют протоколы без установления соединения. IP имеет довольно плохую совместимость с сетями ATM, ориентированными на установку соединения. Этот факт крайне негативно сказывается на популярности ATM.

И что важнее всего, разработчикам Ethernet удалось добиться хороших показателей по самым главным направлениям. Скорости выросли на несколько порядков, в систему были внедрены коммутаторы и концентраторы, но эти изменения никак не коснулись программного обеспечения. Помимо этого, они допускают использование существующей кабельной разводки в течение довольно длительного времени. Если продавец скажет: «Вот отличная новая сетевая система! Она работает просто фантастически быстро и надежно! Вам необходимо только выкинуть весь ваш старый железный хлам и стереть все старые программы», — у него возникнут проблемы с объемами продаж.

Многие альтернативные технологии, о которых вы, вероятно, даже не слышали, в моменты своего появления были даже быстрее тогдашнего Ethernet. Помимо ATM, этот список включает FDDI и волоконно-оптический канал (FC — Fibre Channel) — две оптические локальные сети на базе кольца. Обе были несовместимы с Ethernet. Ни одна не выжила. Они были слишком сложны, что приводило к усложнению микросхем и повышению цен. Урок очень прост: БПД — будь проще, дурачок (KISS — Keep It Simple, Stupid). Потом оказалось, что Ethernet догнал и перегнал их по скорости работы, по пути заимствуя составляющие технологий конкурентов (например, кодирование 4B/5B у FDDI и 8B/10B у FC). У соперников не осталось никаких преимуществ, и они либо тихо скончались, либо сбежали в узкоспециализированные сферы применения.

Создается впечатление, что области применения Ethernet продолжат расширяться. 10-Gigabit Ethernet освободился от ограничений максимального расстояния, накладываемых CSMA/CD. Много внимания уделяется Ethernet операторского класса (carrier-grade Ethernet), который позволит сетевым провайдерам предлагать основанные на Ethernet услуги своим клиентам в городских и глобальных сетях (Fouli, Maler, 2009). Это приложение способно передавать кадры Ethernet на большие расстояния по оптоволоконному кабелю и требует усовершенствования возможностей управления, для того чтобы операторы смогли предлагать пользователям надежные высококачественные услуги. Скоростные сети также находят применение в системных платах, соединяющих компоненты в больших маршрутизаторах или серверах. Оба этих варианта использования представляют собой лишь дополнения к задаче пересылки кадров между компьютерами в офисах.

4.4. Беспроводные локальные сети

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

Основной стандарт беспроводных локальных сетей — это 802.11. Некоторую общую информацию мы уже приводили в разделе 1.5.3. Теперь более пристальный взгляд обратим на технологическую сторону стандарта 802.11. В последующих разделах речь пойдет о стеке протоколов, методах радиопередачи (на физическом уровне), протоколе подуровня MAC, структуре кадра и сервисах. Дополнительную информацию о стандарте 802.11 можно найти в издании (Gast, 2005). Чтобы получить информацию из первых рук, обратитесь к официальному техническому описанию стандарта IEEE 802.11-2007.

4.4.1. Стандарт 802.11: архитектура и стек протоколов

Сети 802.11 можно использовать в двух режимах. Самый популярный режим — это подключение клиентов, таких как ноутбуки и смартфоны, к другой сети, например внутренний сети компании или Интернету. Такая схема показана на рис. 4.20, а. В инфраструктурном режиме (infrastructure mode) каждый режим связывается с точкой доступа (Access Point, AP), которая, в свою очередь, подключена к сети. Клиент отправляет и получает пакеты через точку доступа. Несколько точек доступа можно соединить вместе, обычно в кабельную сеть под названием распределительная система (distribution system). Так формируется расширенная сеть 802.11. В данном случае клиенты могут отправлять кадры другим клиентам через их точки доступа.

Второй режим, показанный на рис. 4.20, б, называется произвольной сетью (ad hoc network). Это набор компьютеров, которые связаны таким образом, чтобы они могли напрямую отправлять кадры друг другу. Точка доступа не используется. Поскольку доступ в Интернет — революционная технология в беспроводных соединениях, произвольные сети не очень популярны.

Рис. 4.20. Архитектура сети стандарта 802.11: а — инфраструктурный режим; б — произвольный режим

Теперь взглянем на протоколы. Все протоколы, используемые семейством стандартов 802.х, включая 802.11 и Ethernet, схожи по структуре. Часть стека протоколов изображена на рис. 4.21. Стек одинаков для клиентов и для точек доступа. Физический уровень практически соответствует физическому уровню в модели OSI, а вот канальный уровень во всех протоколах 802.х разбит на два или более подуровня. Что касается

802.11, то подуровень MAC (подуровень управления доступом к среде) отвечает за распределение канала, то есть за то, какая станция будет передавать следующей. Над MAC в иерархии находится подуровень LLC (управления логическим соединением), задача которого состоит в том, чтобы сделать различия стандартов 802.х невидимыми для сетевого уровня. Это могло бы стать очень ответственной задачей, но в настоящее время ключевым слоем считается LLC; именно он отвечает за идентификацию протокола (например, IP), информация о котором передается в кадре 802.11.

После первого появления в 1997 году физический уровень обзавелся несколькими новыми методами передачи. Два первоначальных метода, инфракрасная передача (как

в пульте дистанционного управления телевизором) и режим скачкообразного изменения частоты в диапазоне 2,4 ГГц, сегодня не используются. Третий из первоначальных методов, широкополосный сигнал с прямой последовательностью на скорости 1 или 2 Мбит/с в диапазоне 2,4 ГГц, был расширен и завоевал популярность со скоростями до 11 Мбит/с. Этот стандарт известен под названием 802.11b.

Рис. 4.21. Часть стека протоколов 802.11

Для того чтобы дать фанатам беспроводных сетей такое желанное увеличение скорости, в 1999 и 2003 годах были представлены новые методы передачи на основе схемы OFDM (Orthogonal Frequency Division Multiplexing), описанной ранее в разделе 2.5.3. Первый метод называется 802.11a и работает в другом диапазоне частот, 5 ГГц. Второй остался в диапазоне 2,4 ГГц для обеспечения совместимости. Он называется 802.11g. Оба работают на скоростях до 54 Мбит/с.

Совсем недавно, в октябре 2009 года, в рамках стандарта 802.11n была завершена работа над методами передачи данных, которые одновременно используют несколько антенн на приемнике и передатчике, что дает очередной выигрыш в скорости. Благодаря четырем антеннам и более широким каналам стандарт 802.11 теперь определяет скорости до поразительных 600 Мбит/с.

Сейчас мы изучим вкратце все эти методы передачи. Мы рассмотрим только используемые методы, отбросив устаревшие стандарты 802.11. Технически, они относятся к физическому уровню, которому была посвящена, вообще говоря, вся глава 2. Но из-за того, что они так тесно связаны с ЛВС вообще и с ЛВС стандарта 802.11 в частности, мы обращаемся к ним здесь.

4.4.2. Стандарт 802.11: физический уровень

Все рассматриваемые ниже методы передачи данных позволяют передать кадр подуровня MAC с одной станции на другую по радиоканалу. Отличаются они используемыми технологиями и достижимыми скоростями. Детальное рассмотрение этих методов выходит за рамки данной книги, мы лишь дадим краткое описание, которое, возможно, заинтересует читателей и снабдит их необходимыми терминами для поиска более подробной информации где-либо еще (см. также раздел 2.5).

Все методы стандарта 802.11 используют радиосигналы ближнего радиуса действия в диапазоне частот ISM 2,4 ГГц или 5 ГГц (подробнее об этом см. раздел 2.3.3). Преимущество этих диапазонов в том, что они не требуют лицензирования, то есть доступны для любого передатчика, отвечающего небольшому числу ограничений (излучаемая мощность до 1 Вт, хотя для большинства передатчиков в беспроводных сетях характерна модность 50 мВт). К сожалению, этот факт также известен производителям автоматических гаражных дверей, беспроводных телефонов, микроволновых печей и множества других устройств, конкурирующих за один и тот же спектр частот с ноутбуками. Диапазон 2,4 ГГц более населен, чем диапазон 5 ГГц, поэтому для некоторых приложений предпочтительнее использовать последний, несмотря на меньший радиус действия (из-за более высокой частоты).

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

Первый метод передачи, на который мы взглянем, — это 802.11b. Это технология расширенного спектра, поддерживающая скорости 1, 2, 5,5 и 11 Мбит/с, хотя на практике почти всегда удается удерживать ее на самом высоком уровне. Она похожа на систему CDMA, с которой мы познакомились ранее, за исключением того, что здесь только один код расширения спектра, который используется всеми пользователями. Расширение применяется для удовлетворения требованию FCC о том, что мощность должна быть распределена по диапазону ISM. Для стандарта 201.11b используется последовательность Баркера (Barker sequence). Ее отличительная особенность заключается в том, что автокорреляция низка, за исключением случаев, когда последовательности выровнены. Благодаря этому получатель может захватить начало передачи. Для того чтобы пересылать данные на скорости 1 Мбит/с, последовательность Баркера комбинируется с модуляцией BPSK, и с каждыми 11 чипами отправляется 1 бит. Чипы пересылаются со скоростью 11 Мчипов/с. Чтобы достичь скорости 2 Мбит/с, последовательность комбинируется с модуляцией QPSK, и с каждыми 11 чипами отправляются 2 бита. На более высоких скоростях дело обстоит по-другому. Вместо последовательности Баркера для конструирования кодов применяется техника под названием CCK (Complementary Code Keying, схема ключей дополнительного кода). На скорости 5,5 Мбит/с в каждом 8-чиповом коде отправляется 4 бита, а на скорости 11 Мбит/с — 8 бит.

Переходим к 802.11a, который поддерживает скорости до 54 Мбит/с в 5-гигагерцо-вом диапазоне ISM. Можно было бы подумать, что 802.11a появился раньше 802.11b, но это не так. Хотя группа 802.11a была основана раньше, стандарт 802.11b первым получил одобрение. Соответствующие продукты вышли на рынок раньше продуктов 802.11a частично еще и из-за сложностей работы в более высоком диапазоне 5 ГГц.

Метод 802.11a основан на технологии OFDM (Orthogonal Frequency Division Multiplexing), так как она эффективно использует спектр и устойчива к искажению беспроводного сигнала, например, из-за многолучевого распространения. Биты параллельно отправляются по 52 поднесущим, из которых 48 содержат данные и 4 служат для синхронизации. Каждый символ длится 4 мкс и отправляет 1, 2, 4 или 6 бит. Биты кодируются для исправления ошибок, для этого применяется сверточный код. Поэтому только 1/2, 2/3 или 3/4 бит не являются избыточными. В разных комбинациях 802.11a может обеспечивать восемь разных показателей скорости, от 6 до 54 Мбит/с. Это значительно выше, чем у 802.11b, к тому же в диапазоне 5 ГГц намного меньше помех. Однако радиус действия 802.11b примерно в семь раз дальше, чем у 802.11a, что во многих ситуациях бывает крайне важно.

Несмотря на большую дальность действия, разработчики 802.11b не собирались давать этому молодому да раннему стандарту шансов на победу в соревновании скоростей. К счастью, в мае 2002 года FCC отменила давнее правило, требующее, чтобы все беспроводное коммуникационное оборудование, работающее в США в диапазонах ISM, применяло расширение спектра, поэтому стало возможным запустить работу над 802.11g — этот стандарт был одобрен комитетом IEEE в 2003 году. Он копирует методы модуляции OFDM стандарта 802.11a, но вместе с 802.11b используется в ограниченном диапазоне ISM 2,4 ГГц. Он предлагает те же скорости, что и 802.11a (от 6 до 54 Мбит/с) плюс, разумеется, совместимость с любыми устройствами 802.11b, которые могут оказаться рядом. Все эти различия зачастую сбивают простых пользователей с толку, поэтому продукты обычно поддерживают 802.11a/b/g в одной общей плате.

Не сбираясь останавливаться на достигнутом, комитет IEEE начал работу над физическим уровнем 802.11n, характеризующимся очень высокой пропускной способностью. Он был одобрен в 2009 году. Цель 802.11n — обеспечить пропускную способность не менее 100 Мбит/с, устранив все накладные расходы беспроводной связи. Для этого требуется увеличение базовой скорости как минимум в четыре раза. Комитет удвоил ширину каналов с 20 до 40 МГц и снизил накладные расходы на пересылку кадров, разрешив совместную отправку целой группы кадров. Что еще важнее, в стандарте 802.11n предусмотрено использование до четырех антенн для пересылки до четырех потоков информации одновременно. Сигналы потоков смешиваются на стороне получателя, но их можно разделить с помощью коммуникационных техник MIMO (Multiple Input Multiple Output, несколько входов — несколько выходов). Наличие нескольких антенн дает огромный выигрыш в скорости либо больший радиус действия и повышение надежности. MIMO, как и OFDM, — это одна из тех хитрых коммуникационных идей, которые в корне меняют дизайн беспроводных сетей и о которых мы наверняка нередко будем слышать и в будущем. Краткое описание техники использования нескольких антенн в стандарте 802.11 см в (Halperin и др., 2010).

4.4.3. Стандарт 802.11: протокол подуровня управления доступом к среде

Однако вернемся из области электротехники в область компьютерных наук. Протокол подуровня MAC (напомним, MAC расшифровывается как Medium Access Control — Управление доступом к среде) в стандарте 802.11 довольно сильно отличается от аналогичного протокола Ethernet вследствие двух фундаментальных факторов, характерных для беспроводного обмена данными.

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

Вместо этого 802.11 пытается избегать коллизий за счет протокола CSMA/CA (CSMA with Collision Avoidance, CSMA с предотвращением коллизий). Концепция данного протокола схожа с концепцией CSMA/CD для Ethernet, где канал прослушивается перед началом отправки, а период молчания после коллизии вычисляется экспоненциально. Однако если у станции есть кадр для пересылки, то она начинает цикл с периода молчания случайной длины (за исключением случаев, когда она давно не использовала канал, и он бездействует). Станция не ожидает коллизий. Число слотов, в течение которых она молчит, выбирается в диапазоне от 0 до, скажем, 15 в случае физического уровня OFDM. Станция дожидается бездействия канала в течение короткого периода времени (называемого DIFS; подробнее о нем ниже) и отсчитывает слоты бездействия, приостанавливая отсчет на время отправки кадров. Свой кадр она отправляет, когда счетчик достигает нуля. Если кадр проходит успешно, то адресат немедленно отправляет обратно короткое подтверждение. Если подтверждение отсутствует, делается вывод, что произошла ошибка — коллизия или иная. В таком случае отправитель удваивает период молчания и повторяет попытку, продолжая экспоненциально наращивать длину паузы (как с Ethernet), пока кадр не будет успешно передан или пока не будет достигнуто максимальное число повторов.

Пример некоторой временной шкалы приводится на рис. 4.22. Станция A отправляет кадр первой. Пока станция A занята отправкой, станции B и C переходят в режим готовности к отправке. Они видят, что канал занят, и дожидаются бездействия канала. Вскоре после получения станцией A подтверждения канал переходит в режим бездействия. Однако вместо того чтобы сразу же отправлять кадры (что привело бы к коллизии), станции B и C начинают свои периоды молчания. Станция C выбирает короткий период молчания, поэтому ей удается отправить данные первой. Станция приостанавливает обратный отсчет, когда видит, что канал занят станцией C, и возобновляет только после получения станцией C подтверждения. Вскоре период молчания станции B завершается, и она также отправляет кадр.

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

Такой режим работы называется DCF (Distributed Coordination Function, распределенная координация). Все станции действуют независимо, централизованный контроль не осуществляется. Стандарт также включает необязательный режим PCF (Point Coordination Function, сосредоточенная координация), в котором всей деятельностью в ячейке управляет точка доступа — как базовая станция сотовой сети.

Однако PCF на практике не применяется, потому что невозможно запретить станциям из соседней сети передавать конкурирующий трафик.

Рис. 4.22. Отправка кадра с протоколом CSMA/CA

Вторая проблема заключается в том, что области передачи разных станций не обязательно совпадают. В кабельной сети система спроектирована таким образом, чтобы все станции могли слышать друг друга. Сложности передачи радиосигналов не позволяют обеспечить такое постоянство для беспроводных станций. Следовательно, возможно возникновение ситуаций, таких как проблема скрытой станции — мы уже упоминали о ней ранее, а сейчас приводим еще и иллюстрацию на рис. 4.23, а. Поскольку не все станции могут слышать друг друга, передача, идущая в одной части ячейки, может быть просто не воспринята станцией, находящейся в другой ее части. В приведенном на рисунке примере станция С передает данные станции В. Если станция А прослушает канал, она не обнаружит ничего подозрительного и сделает ложный вывод о том, что она имеет право начать передачу станции В. Это решение приводит к коллизии.

Кроме того, есть и обратная проблема, показанная на рис. 4.23, б. Здесь В хочет отправить данные для станции С и прослушивает канал. Услышав, что в нем уже осуществляется какая-то передача, станция В делает опять-таки ложный вывод о том, что передача для С сейчас невозможна. Между тем, станция А — источник сигнала, который смутил станцию В, — может, на самом деле, осуществлять передачу для станции D (на рисунке не показана). Таким образом, теряется возможность передать информацию.

Для того чтобы разрешить непонимание относительно того, какая станция будет отправлять данные, в стандарте 802.11 прослушивание канала определяется на физическом и виртуальном уровнях. При физическом прослушивании среда просто проверяется на наличие сигнала. Виртуальное прослушивание заключается в том, что каждая станция ведет логический журнал использования канала, отслеживая NAV (Network Allocation Vector, вектор распределения сети). Каждый кадр содержит поле NAV, которое сообщает, как долго последовательность, включающая данный кадр, будет передаваться. Станции, услышавшие этот кадр, понимают, что канал будет занят в течение периода, указанного в NAV, даже если физический сигнал в канале отсутствует. Например, NAV для кадров данных включает также время, необходимое для отправки подтверждения. Все станции, услышавшие этот кадр данных, воздерживаются от пересылки данных в течение периода отправки подтверждения, независимо от того, слышали ли они его в канале.

Рис. 4.23. Проблема: а — скрытой станции; б — засвеченной станции

Необязательный механизм RTS/CTS с помощью NAV запрещает станциям отправлять кадры одновременно со скрытыми станциями. Пример показан на рис. 4.24. В этом примере станция A хочет передать данные станции B. Станция C находится в зоне действия (то есть слышит) А, а также, возможно, в зоне действия В, но это не имеет значения. Станция D входит в зону действия B, но не входит в зону действия А.

Протокол начинает работать тогда, когда А решает, что ей необходимо послать данные В. А посылает станции В кадр RTS, запрашивая разрешение на передачу. Если В может принять данные, она отсылает обратно подтверждение о том, что канал чист — кадр CTS. После приема CTS А отправляет кадр и запускает таймер ACK. В случае корректного приема В генерирует кадр ACK, завершающий передачу. Если интервал времени таймера на станции A истекает прежде, чем получен ACK, то считается, что произошла коллизия, и весь алгоритм работы протокола повторяется с самого начала после периода молчания.

Теперь рассмотрим этот же процесс с точки зрения станций C и D. C находится в зоне действия А, поэтому она также принимает кадр RTS и понимает, что скоро по каналу будут передаваться какие-то данные. Исходя из информации, содержащейся в RTS, станция С может предположить, сколько времени займет передача последовательности, включая конечный ACK. Поэтому, чтобы не мешать другим, она воздерживается от передачи данных, пока обмен не будет завершен. Для этого она обновляет свою запись NAV, указывая, что канал занят, как показано на рис. 4.24. Станция D не слышит RTS, зато слышит CTS и также выставляет NAV Обратите внимание: сигналы NAV не передаются, а являются лишь внутренними напоминаниями станций о том, что нужно хранить молчание в течение определенного промежутка времени.

Рис. 4.24. Использование прослушивания виртуального канала в протоколе CSMA/CA

Однако, несмотря на теоретическую привлекательность модели RTS/CTS, это один из тех методов, практическая реализация которых провалилась. Есть несколько причин, почему она используется так редко. Она не рассчитана на короткие кадры (которые отправляются вместо RTS) и на присутствие точек доступа (которые, по определению, должны быть слышны всем). В других ситуациях она также замедляет работу. RTS/CTS в стандарте 802.11 немного отличается от протокола MACA, с которым мы познакомились в разделе 4.2, потому что каждый, кто получает RTS или CTS, сохраняет молчание в течение какого-то промежутка, для того чтобы подтверждение ACK сумело пройти по каналу без коллизий. По причине этого проблема засвеченной станции не решается, как при использовании протокола MACA, устраняется только проблема скрытых станций. Чаще всего скрытых станций совсем немного, и CSMA/ CA и так помогает им. Эта технология замедляет станции, которым по какой-либо причине не удается успешно передать данные, для того чтобы повысить вероятность удачной пересылки.

CSMA/CA с физическим и виртуальным прослушиванием составляет суть протокола 802.11. Однако есть несколько других механизмов, разработанных для того же стандарта. Каждый из этих механизмов вызван определенными потребностями, связанными с фактическими условиями.

Первая потребность — это надежность. В противоположность проводным каналам, беспроводные шумны и ненадежны, в какой-то степени из-за влияния других устройств, таких как СВЧ-печи, работающих в том же диапазоне ISM. Использование подтверждений и повторных передач мало помогает, если вероятность передачи кадра мала.

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

Другая стратегия улучшить шанс кадра дойти неповрежденным состоит в том, чтобы посылать более короткие кадры. Если вероятность ошибки в одном бите равна р, то вероятность того, что n-битный кадр будет принят корректно, равна (1 - p)n. Например, для р = 10-4 вероятность корректной передачи полного Ethemet-кадра длиной 12 144 бит составляет менее 30 %. Большая часть кадров будет потеряна. Но если длина кадров будет составлять только одну треть (4048 бит), то две трети их будут получены правильно. Теперь большинство кадров пройдет, и будет необходимо меньше повторных передач.

Использование более коротких кадров может быть реализовано сокращением максимального размера сообщения, которое принимается от сетевого уровня. С другой стороны, 802.11 позволяет разделять кадры на мелкие кусочки, названные фрагментами (fragments), каждый со своей контрольной суммой. Размер фрагмента не фиксирован, а является параметром, который может быть скорректирован точкой доступа. Фрагменты нумеруются и подтверждаются индивидуально с использованием протокола с ожиданием (то есть отправитель не может передать фрагмент с номером k + 1, пока не получит подтверждения о доставке фрагмента с номером k). Они идут один за другим с подтверждением (и возможно повторной передачей) между ними, пока или весь кадр не будет передан успешно, или время передачи не достигнет позволенного максимума. Механизм NAV удерживает станции от передачи только до прихода первого подтверждения о доставке. Но есть и другой механизм (он описан ниже), позволяющий получателю принять всю пачку фрагментов, без кадров от других станций между ними.

Вторая потребность, которую мы обсудим, — экономия энергии. Время работы от аккумулятора для мобильных беспроводных устройств всегда представляет проблему. Стандарт 802.11 обращает внимание на проблему управления электропитанием так, чтобы клиенты не тратили энергию впустую, когда у них нет посылаемой или получаемой информации.

Основной механизм для экономии энергии основывается на кадрах «маяках» (beacon frames). Это периодические широковещательные сообщения точки доступа (например, каждые 100 мс). Кадры сообщают клиентам о присутствии точки доступа и несут системные параметры, такие как идентификатор, время, интервал до следующего маяка и настройки безопасности.

Клиенты могут установить бит управления электропитанием в кадрах, которые они посылают в точку доступа, чтобы сообщить ей, что они входят в энергосберегающий режим (power-save mode). В этом режиме клиент может дремать, и точка доступа будет буферизовать предназначенный для него трафик. Чтобы проверить наличие входящего трафика, клиент просыпается для каждого маяка и проверяет карту трафика, которую ему посылают как часть маяка. Эта карта говорит клиенту о наличие буферизованного трафика. Если он есть, клиент посылает сообщение опроса в точку доступа, и она посылает буферизованный трафик. Затем клиент может вернуться в спящий режим до следующего маяка.

В 2005 году к 802.11был добавлен другой энергосберегающий механизм, названный APSD (Automatic Power Save Delivery — автоматический переход в режим сохранения энергии). С этим новым механизмом точка доступа буферизирует кадры и посылает их клиенту сразу после того, как клиент посылает кадры в точку доступа. Клиент может заснуть, пока у него нет большего количества трафика для отправки (и получения). Этот механизм хорошо работает на таких приложениях, как

IP-телефония, у которых часто есть трафик в обоих направлениях. Например, беспроводной IP-телефон мог бы использовать этот механизм, чтобы посылать и получать кадры каждые 20 мс, что намного чаще, чем интервал маяка (100 мс), и находится в спящем режиме в промежутках.

Третья и последняя потребность, которую мы исследуем, — это качество обслуживания. Когда трафик IP-телефонии в предыдущем примере конкурирует с трафиком соединения равноправных узлов ЛВС, пострадает трафик IP-телефонии. Он будет отложен в соревновании с трафиком соединения равноправных узлов ЛВС высокой пропускной способности, даже при том, что пропускная способность IP-телефонии низка. Эти задержки, вероятно, ухудшат голосовые вызовы. Чтобы предотвратить это ухудшение, мы хотели бы позволить трафику IP-телефонии идти перед трафиком соединения равноправных узлов ЛВС, как имеющего более высокий приоритет.

В IEEE 802.11 есть умный механизм, обеспечивающий этот вид качества обслуживания, который был введен в 2005 году как набор расширений под именем 802.11e. Он работает, расширяя CSMA/CA с тщательно определенными интервалами между кадрами. После того как кадр послан, прежде чем любая станция может послать кадр, требуется определенное количество времени простоя, чтобы проверить, что канал больше не занят. Эта уловка должна определить различные временные интервалы для различных видов кадров.

На рис. 4.25 изображено пять интервалов. Интервал между регулярными кадрами данных называется DIFS (DCF InterFrame Spacing межкадровый интервал DCF). Любая станция может попытаться захватить канал, чтобы послать новый кадр после того, как среда была неактивна для DIFS. Применяются при этом обычные правила борьбы, включая двоичную экспоненциальную выдержку в случае коллизии.

Самый короткий интервал — это SIFS (Short InterFrame Interval короткий межкадровый интервал). Он используется для того, чтобы одна из сторон в диалоге могла получить шанс начать первой. Примеры включают разрешение получателю послать ACK, другие последовательности кадров управления, такие как RTS и CTS, или разрешение отправителю передать пакет фрагментов. Отправка следующего фрагмента после ожидания только SIFS препятствует тому, чтобы другая станция вмешалась с кадром в середине обмена.

Рис. 4.25. Межкадровые интервалы в стандарте 802.11

Два интервала AIFS (Arbitration InterFrame Space межкадровый арбитражный интервал) показывают примеры двух различных уровней приоритета. Короткий интервал, AIFSp короче чем DIFS, но длиннее, чем SIFS. Он может использоваться точкой доступа, чтобы переместить голос или другой приоритетный трафик в начало очереди. Точка доступа будет ждать более короткого интервала, прежде чем пошлет голосовой трафик, и, таким образом, пошлет его раньше регулярного трафика. Длинный интервал, AIFS4, больше чем DIFS. Он используется для фонового трафика, который может быть задержан до окончания регулярного трафика. Прежде чем послать этот трафик, точка доступа будет ждать в течение более длинного интервала, давая возможность сначала передать регулярный трафик. Полный механизм качества обслуживания определяет четыре различных приоритетных уровня, у которых есть различные параметры выдержки, а также различные параметры времени ожидания.

Последний временной интервал называется EIFS (Extended InterFrame Spacing расширенный межкадровый интервал). Он используется только той станцией, которая только что получила испорченный или неопознанный кадр и хочет сообщить о проблеме. Идея в том, что приемник может сразу не сообразить, что происходит, и ему нужно выждать в течение какого-то интервала, чтобы не прервать своим возмущенным возгласом идущий в это время диалог между станциями.

Дальнейшая часть расширений, обеспечивающих качество обслуживания, — понятие возможности передачи (transmission opportunity) или TXOP. Первоначальный механизм CSMA/CA позволял станциям посылать один кадр за один раз. Эта схема была прекрасна, пока диапазон скоростей не увеличился. В 802.11a/g одна станция могла бы посылать кадры со скоростью 6 Мбит/с, а другая — 54 Мбит/с. Каждой из них надо послать один кадр, но первой станции нужно для отправки ее кадра в 9 раз больше времени (не считая фиксированных накладных расходов), чем второй. У этого неравенства есть неприятный побочный эффект замедления быстрого отправителя, который конкурирует с медленным отправителем, примерно до скорости медленного отправителя. Например, снова игнорируя фиксированные накладные расходы, работая по отдельности отправители реализовывали бы свои собственные скорости 6 Мбит/с и 54 Мбит/с, а работая вместе они оба получат в среднем скорость 5,4 Мбит/с. Что большая неприятность для быстрого отправителя. Эта проблема известна как аномалия скорости (rate anomaly) (Heusse и др., 2003).

При использовании TXOP каждая станция получает одинаковое количество эфирного времени, а не одинаковое количество кадров. Станции, которые посылают на более высокой скорости, получат в течение своего эфирного времени более высокую пропускную способность. В нашем примере отправители, совместно работающие со скоростями 6 и 54 Мбит/с, теперь достигнут скоростей 3 и 27 Мбит/с, соответственно.

4.4.4. Стандарт 802.11: структура кадра

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

В качестве примера мы рассмотрим формат информационного кадра. Он показан на рис. 4.26. Вначале идет поле Управление кадром (Frame Control). Оно содержит 11 вложенных полей. Первое из них — Версия протокола, установлено в 00 (2 бита). Именно оно позволит будущим версиям 802.11 работать одновременно в одной ячейке сети. Затем следуют поля Тип (информационный, служебный или управляющий) и Подтип (например, RTS или CTS). Для обычного кадра данных (без указания качества обслуживания) они установлены как бинарные 10 и 0000. Биты К DS и От DS говорят о направлении движения кадра: в сеть или из сети, соединенной с точкой доступа, которая называется распределительной системой (distribution system). Бит Дополнительные фрагменты говорит о том, что далее следует еще один фрагмент. Бит Повтор маркирует повторно посылаемый кадр. Бит Управление питанием используется станцией-отправителем для указания на свое переключение в режим пониженного энергопотребления или на выход из этого режима. Бит Продолжение говорит о том, что у отправителя имеются еще кадры для пересылки. Бит Шифрование является индикатором использования шифрования в теле кадра. Наконец, установленный бит Порядок говорит приемнику о том, что кадры с этим битом должны обрабатываться строго по порядку.

Рис. 4.26. Информационный кадр стандарта 802.11

Второе основное поле информационного кадра — это поле Длительность. В нем задается время в микросекундах, которое будет потрачено на передачу кадра и подтверждения. Это поле присутствует во всех типах кадров, в том числе в служебных кадрах, и именно в соответствии с ним станции выставляют признаки NAV.

Далее следуют адреса. Кадры данных содержат три адреса в формате, соответствующем стандарту IEEE 802. Понятно, что нужны адреса отправителя и получателя, но что же содержится в третьем?

Помните, что точка доступа — это просто пункт ретрансляции кадров, когда они движутся между клиентом и другой точкой сети, возможно удаленным клиентом или интернет-порталом. Третий адрес — адрес этой удаленной конечной точки.

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

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

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

Управляющие кадры имеют такой же формат, как формат информационных кадров, плюс формат для части данных, которая меняется в зависимости от подтипа (например, параметры в кадрах «маяках»).

Служебные кадры короткие. Как и во всех кадрах, в них содержится Управление кадром, Длительность и Контрольная последовательность кадра. При этом они могут иметь только один адрес и не иметь поля Данные. Ключевой здесь является информация, содержащаяся в поле Подтип (RTS, CTS или ACK).

4.4.5. Сервисы

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

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

Реассоциация (reassociation) позволяет станции сменить точку доступа. Эта возможность полезна при перемещении станции от одной точки доступа к другой в той же расширенной 802.11 ЛВС, по аналогии с передачей в сотовой сети. Если она проходит корректно, то при переходе никакие данные не теряются. (Однако, как и в сети Ethernet, в стандарте 802.11 все услуги предоставляются лишь с обязательством приложения максимальных усилий к их исполнению, но не с гарантией.) По инициативе мобильной станции или точки доступа может быть произведена дизассоциация (disassociate), то есть разрыв отношений. Она требуется при выключении станции или ее уходе из зоны действия точки доступа. Точка доступа также может быть инициатором дизассоциации, если, например, она временно выключается для проведения технического обслуживания.

Прежде чем станции смогут посылать кадры через точку доступа, они должны пройти аутентификацию (authenticate). В зависимости от выбора схемы безопасности аутентификация поддерживается по-разному. Если сети 802.11 «открыты», их разрешают использовать любому. Если нет — для аутентификации нужны параметры учетной записи. Рекомендуемая схема, названная WPA2 (WiFi Protected Access 2 — WiFi Защищенный Доступ 2), обеспечивает безопасность как определено стандартом 802.111. (Просто WPA — временная схема, которая обеспечивает подмножество 802.11i. Мы пропустим ее и перейдем прямо к полной схеме.) С WPA2 точка доступа может взаимодействовать с сервером аутентификации, у которого есть имя пользователя и база данных паролей, чтобы определить, разрешено ли станции получить доступ к сети. Либо может быть сконфигурирован предустановленный ключ (pre-shared key), который является необычным названием сетевого пароля. Несколько кадров с запросом и ответом пересылаются между станцией и точкой доступа, что позволяет станции доказать, что у нее есть правильные учетные данные. Этот обмен происходит после ассоциации.

Схема, которая использовалась до WPA, называется WEP (Wired Equivalent Privacy приватность на уровне проводной связи). Для этой схемы аутентификация с предустановленным ключом выполнялась перед ассоциацией. Однако ее польза не велика из-за недостатков конструкции, которые делают WEP легко взламываемым. Первая практическая демонстрация взлома WEP произошла, когда Адам Стаббле-филд был летним стажером в AT&T (Stubblefield и др., 2002). Он смог написать код и проверить атаку за одну неделю, большая часть которой была потрачена на получение разрешения администрации на покупку карт WiFi, необходимых для эксперимента. Программное обеспечение для взлома паролей WEP теперь есть в свободном доступе.

Когда кадры достигают точки доступа, служба распределения (distribution service)

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

Служба интеграции (integration service) поддерживает трансляцию, необходимую, если кадр нужно выслать за пределы сети стандарта 802.11 или если он получен из сети не этого стандарта. Типичный случай здесь — соединение между беспроводной ЛВС и Интернетом.

Доставка данных (data delivery). Собственно говоря, именно этот сервис является ключевым во всей работе сети. Ведь сеть 802.11 существует для обмена данными. Эта служба позволяет станциям передавать и получать данные по протоколам, которые мы описали ранее в этой главе. Поскольку стандарт 802.11 основан на стандарте Ethernet, а в последнем доставка данных не является гарантированной на 100 %, то для беспроводных сетей это тем более верно. Верхние уровни должны заниматься обнаружением и исправлением ошибок.

Беспроводная передача — это широковещательный сигнал. Для сохранения конфиденциальности информации, посланной по беспроводной ЛВС, она должна быть зашифрована. Эта цель достигается службой конфиденциальности (privacy service), которая управляет деталями шифрования и дешифрования. Алгоритм шифрования для WPA2 основан на AES (Advanced Encryption Standard улучшенный стандарт шифрования), американском правительственном стандарте, одобренном в 2002 году. Ключи, которые используются для шифрования, определяются во время процедуры аутентификации.

Для обработки трафика с различными приоритетами имеется служба планирования трафика QOS (QOS trffic scheduling). Она использует протоколы, которые мы описали, чтобы дать голосовому и видео трафику преимущество перед трафиком «с максимальными усилиями» и фоновым трафиком. Сопутствующая служба также обеспечивает синхронизацию более высокого уровня. Это позволяет станциям координировать свои действия, что может быть полезным для обработки мультимедиа.

Наконец, есть две службы, которые помогают станциям управлять использованием спектра. Регулирование мощности передатчика (transmit power control) дает станциям информацию, которая нужна им, чтобы соответствовать установленным нормативным пределам мощности передачи, которые варьируются в зависимости от региона. Служба динамического выбора частоты (dynamic frequency selection) дает станциям информацию, необходимую, чтобы избежать передачи в частотном диапазоне 5 ГГц, который используется радарами.

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

4.5. Широкополосные беспроводные сети

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

Предложений действительно много. Проблема только в том, что прокладка волоконно-оптического или коаксиального кабеля к миллионам абонентов обходится очень дорого. Что же делать?

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

Для стимулирования рынка, IEEE сформировал группу, чтобы стандартизировать широкополосную городскую беспроводную сеть. Следующее число в нумерации 802 было 802.16, таким образом, стандарт получил этот номер. Неофициально технологию называют WiMAX (Worldwide Interoperability for Microwave Access). Мы будем использовать термины 802.16 и WiMAX попеременно.

Впервые стандарт 802.16 был апробирован в декабре 2001 года. Ранние версии обеспечили беспроводную местную линию связи между фиксированными точками с прямой видимостью друг друга. Эта схема вскоре была изменена, чтобы сделать WiMAX более конкурентоспособной альтернативой кабелю и DSL для доступа к Интернету. К январю 2003 года стандарт 802.16 был пересмотрен, чтобы поддержать связи вне прямой видимости с использованием технологии OFDM в частотах между 2 и 10 ГГц. Это изменение сделало установку намного легче, хотя станции все еще были с фиксированными местоположениями. Угрозу представлял рост сотовых сетей поколения 3G, обещающий высокие скорости передачи данных и подвижность. В ответ к декабрю 2005 года 802.16 снова был улучшен, чтобы позволить подвижность на скоростях транспорта. Мобильный широкополосный доступ к Интернету — цель текущего стандарта, IEEE 802.16-2009.

Подобно некоторым другим стандартам из серии 802, стандарт 802.16 построен с использованием идей модели OSI. Здесь можно найти и уровни, и подуровни, используется схожая терминология, сервисные примитивы и т. п. К сожалению, как и OSI, стандарт 802.16 страдает громоздкостью. Фактически, форум WiMAX (WiMAX Forum) создавался для того, чтобы определить имеющие возможность взаимодействовать подмножества стандарта для коммерческих предложений. В последующих разделах мы приведем краткое описание основных свойств 802.16, но такое исследование является далеко не полным, в нем опущены многие детали. Дополнительную информацию о WiMAX и широкополосных беспроводных сетях в целом вы найдете в (Andrews и др., 2007).

4.5.1. Сравнение стандарта 802.16 с 802.11 и 3G

Казалось бы, зачем провозглашать новый стандарт? Почему бы не использовать 802.11 или 3G? Фактически, WiMAX комбинирует подходы и 802.11 и 3G, становясь больше похожа на технологию 4G.

Как и стандарт 802.11, WiMAX относится к беспроводным технологиям присоединения устройств к Интернету на скоростях порядка нескольких мегабит в секунду, вместо использования кабеля или DSL. Устройства могут быть мобильными, или, по крайней мере, портативными. WiMAX не начинался с добавления данных с низкой скоростью к подобным голосовым сотовым сетям; 802.16 был разработан, чтобы перенести IP пакеты по радиоканалу и соединиться с основанной на IP сетью с минимумом суеты. Чтобы поддержать различные приложения, пакеты могут нести трафик соединения равноправных узлов ЛВС, звонки IP-телефонии или потоковые мультмедиа-трансляции. Так же как и 802.11, WiMAX основан на технологии OFDM, чтобы гарантировать хорошую работу, несмотря на ухудшения беспроводного сигнала, такие как многолучевое затухание, и на технологии MIMO, чтобы достигнуть высоких уровней пропускной способности.

Однако WiMAX больше походит на 3G (и, таким образом, отличается от 802.11) в нескольких ключевых отношениях. Ключевая техническая проблема состоит в том, чтобы достигнуть большой емкости эффективным использованием спектра, так чтобы большое количество абонентов в зоне охвата могли получить высокую пропускную способность. Типичные расстояния, по крайней мере, в 10 раз больше чем для сетей

802.11.    Следовательно, базовые станции WiMAX — более мощные, чем точки доступа

802.11.    Чтобы обработать более слабые сигналы на больших расстояниях, базовая станция использует большую мощность и лучшие антенны, а также выполняет больше работы по обработке ошибок. Чтобы максимизировать пропускную способность, передачи для каждого абонента тщательно распланированы базовой станцией; использование спектра не позволяет использовать CSMA/CA, который с коллизиями может впустую потратить пропускную способность.

Имеющий лицензию спектр — ожидаемый случай для WiMAX, в США это, как правило, приблизительно 2,5 ГГц. Система в целом существенно более оптимизирована, чем 802.11. Сложность стоит того, учитывая крупную сумму денег, потраченную на лицензированный спектр. В отличие стандарта 802.11 результатом является управляемый и надежный сервис с хорошей поддержкой качества обслуживания.

Со всеми этими особенностями 802.16 наиболее близко к сотовым сетям 4-го поколения (4G), которые теперь стандартизируются под именем LTE (Long Term Evolution). В то время как сотовые сети 3G основаны на CDMA и поддерживают речь и данные, сети 4G будут основаны на OFDM с MIMO и ориентированы на передачу данных, а передача голоса будет только одним из приложений. Выглядит так, как будто WiMAX и 4G находятся на встречных курсах с точки зрения технологии и приложений. Возможно, эта конвергенция неудивительна, учитывая, что Интернет — революционная технология, а OFDM и MIMO — самые известные технологии для того, чтобы эффективно использовать спектр.

4.5.2. Стандарт 802.16: архитектура и стек протоколов

Архитектура стандарта 802.16 показана на рис. 4.27. Базовые станции соединяются непосредственно с базовой сетью провайдера, которая, в свою очередь, соединена с Интернетом. Базовые станции общаются со станциями по беспроводному радиоинтерфейсу. Существует два вида станций. Абонентские станции (subscriber stations) остаются в неподвижном местоположении, например, в случае широкополосного доступа к Интернету для домов. Мобильные станции могут обслуживаться в то время, как они перемещаются, например автомобиль, оборудованный WiMAX.

Рис. 4.27. Архитектура стандарта 802.16

Стек протокола стандарта 802.16, который используется в радиоинтерфейсе, показан на рис. 4.28. Общая структура подобна другим стандартам серии 802, однако здесь больше подуровней. Нижний уровень имеет дело с передачей, и здесь мы показали только популярные предложения 802.16, неподвижный и мобильный WiMAX. Для каждого предложения имеется свой физический уровень. Оба уровня работают в лицензированном спектре ниже 11 ГГц и используют OFDM, но по-разному.

Рис. 4.28. Стек протоколов 802.16

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

Затем следует общая часть подуровня MAC. Именно на этом уровне иерархии располагаются основные протоколы — в частности, протоколы управления каналом. Идея состоит в том, что базовая станция полностью контролируют всю систему. Она очень эффективно распределяет очередность передачи нисходящего трафика абонентам и играет главную роль в управлении восходящим трафиком (от абонента к базовой станции). От всех остальных стандартов 802.х MAC-подуровень стандарта 802.16 отличается тем, что он полностью ориентирован на установку соединения. Таким образом, можно гарантировать определенное качество обслуживания при предоставлении услуг телефонной связи и при передаче мультимедиа.

Подуровень сведения отдельных сервисов (service specific convergence sublayer) играет роль подуровня управления логическим соединением в других протоколах 802.х. Его функция заключается в организации интерфейса для сетевого уровня. Чтобы легко объединяться с различными верхними уровнями, определены различные уровни конвергенции. Важный выбор — IP, хотя стандарт определяет отображения также и для таких протоколов, как Ethernet и ATM. Так как IP — протокол без установления соединения, а 802.16 подуровня MAC — модель на основе соединения, этот уровень должен осуществить отображение между адресами и соединениями.

4.5.3. Стандарт 802.16: физический уровень

Большая часть реализаций WiMAX использует лицензируемый спектр около 3,5 ГГц или 2,5 ГГц. Ключевая проблема, как и для 3G, — найти доступный спектр. Поэтому стандарт 802.16 разработан с гибкостью. Он допускает работу в диапазонах от 2 до 11 ГГц. Поддержаны и каналы различных размеров, например 3,5 МГц для неподвижного WiMAX и от 1,25 до 20 МГц для мобильного WiMAX.

Передачи посылаются по этим каналам с применением метода OFDM, который был описан в разделе 2.5.3. По сравнению с 802.11, схема OFDM в 802.16 оптимизирована, чтобы максимально использовать лицензированный спектр и широкую область передачи. Канал разделен на большее количество поднесущих с более длительной продолжительностью символа, чтобы выдержать большие беспроводные деградации сигнала; параметры WiMAX приблизительно в 20 раз больше, чем сопоставимые параметры в 802.11. Например, в мобильном WiMAX есть 512 поднесущих для канала на 5 МГц, и время, чтобы послать символ на каждой поднесущей составляет примерно 100 мкс.

Символы на каждой поднесущей посылаются с модуляцией по схеме QPSK, QAM-16 или QAM-64, которые были описаны в разделе 2.5.3. Если мобильный телефон или абонент расположен недалеко от БС и получаемый сигнал имеет высокий уровень соотношения сигнал/шум, то может применяться QAM-64 с шестью битами на символ. Для достижения удаленных станций с низким уровнем сигнал/шум может быть использована схема QPSK с двумя битами на символ.

Сначала данные кодируются для устранения ошибок с использованием сверточного кодирования (или еще лучшей схемы), как было описано в разделе 3.2.1. Такое кодирование распространено на шумных каналах, чтобы допускать отдельные битовые ошибки, без необходимости выполнять повторные передачи. Фактически, методы модуляции и кодирования должны казаться знакомыми к настоящему времени, так как они используются, как мы изучили, для многих сетей, включая 802.11, кабель и DSL. Конечный результат состоит в том, что базовая станция может передавать информацию со скоростью до 12,6 Мбит/с для нисходящего трафика и до 6,2 Мбит/с для восходящего трафика на канал в 5 МГц и пару антенн.

Разработчикам сетей 802.16 не нравились схемы работы стандартов GSM и DAMPS: и там, и там для нисходящего и восходящего трафика используются эквивалентные по ширине полосы частот. Таким образом, они неявно предполагают, что нисходящего трафика столько же, сколько восходящего. Голосовая связь действительно в основном симметрична, но для доступа в Интернет (и, разумеется, веб-серфинга) обычно нисходящий трафик превосходит восходящий. Соотношение составляет 2:1, 3:1 или еще больше.

Поэтому разработчики выбрали гибкую схему деления канала между станциями, называемую OFDMA (Orthogonal Frequency Division Multiple Access множественный доступ с ортогональным частотным разделением каналов). С OFDMA

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

Имея асимметричный трафик, станции обычно чередуют передачу и прием. Этот метод называют TDD (Time Division Duplex дуплекс с временным разделением).

Альтернативный метод, при котором станция посылает и получает данные в то же самое время (на различных поднесущих частотах), называют FDD (Frequency Division

Duplex дуплекс с частотным разделением). WiMAX допускает оба метода, но пред-почителен TDD, потому что он более гибкий и его легче осуществить.

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

Рис. 4.29. Структура кадра для OFDMA и дуплекса с временным разделением

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

Наконец, абонентские и мобильные станции посылают свои пакеты трафика к базовой станции в восходящих позициях, которые были выделены для них в карте. Один из этих восходящих пакетов зарезервирован для масштабирования (ranging) — это процесс, при котором новые станции корректируют свою синхронизацию и запрашивают начальную полосу пропускания, чтобы соединиться с базовой станцией. Так как никакое соединение на данном этапе не установлено, новые станции только осуществляют передачу и надеются, что коллизий нет.

4.5.4. Стандарт 802.16: протокол подуровня MAC

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

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

Когда абонент соединяется с базовой станцией, выполняется взаимная идентификация с использованием алгоритма RSA с открытым ключом (сертификат X.509). Сама передаваемая информация шифруется с помощью симметричного криптографического ключа: или AES (Rijndael), или DES со сцеплением зашифрованных блоков (cipher block chaining). Целостность данных проверяется алгоритмом SHA-1. Ну что, не очень страшный абзац получился?

Теперь перейдем к общей части подуровня MAC. Подуровень MAC ориентирован на соединение и является точка-многоточечным, это означает, что одна базовая станция общается с несколькими абонентскими станциями. Большая часть этой схемы заимствована у кабельных модемов, в которых один головной узел кабеля управляет обменом с несколькими кабельными модемами в помещениях пользователей.

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

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

1.    Сервис с постоянной битовой скоростью.

2.    Сервис реального времени с переменной битовой скоростью.

3.    Сервис, работающий не в реальном масштабе времени, с переменной битовой

скоростью.

4.    Сервис с обязательством приложения максимальных усилий по предоставлению

услуг.

Все предоставляемые стандартом 802.16 сервисы ориентированы на соединение, и каждое соединение получает доступ к одному из приведенных выше классов сервиса, что определяется при установке связи. Такое решение сильно отличается как от 802.11, так и от Ethernet, где отсутствовали какие-либо намеки на установление соединения на подуровне MAC.

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

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

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

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

4.5.5. Стандарт 802.16: структура кадра

Все кадры подуровня управления доступом к среде (MAC) начинаются с одного и того же заголовка. За ним следует (или не следует) поле данных, и кончается кадр также не обязательным полем контрольной суммы (CRC). Структура кадра показана на рис. 4.30. Поле данных отсутствует в служебных кадрах, которые предназначены, например, для запроса временных интервалов. Контрольная сумма (как ни странно) тоже является необязательной, благодаря тому, что исправление ошибок производится на физическом уровне, и никогда не бывает попыток повторно переслать кадры информации, передающейся в реальном масштабе времени. Так если все равно нет повторных передач, зачем же беспокоить аппаратуру вычислением и проверкой контрольных сумм? Но если контрольная сумма есть, она стандартная для IEEE 802, а подтверждения и повторные передачи используются для надежности.

Давайте кратко рассмотрим поля заголовка (рис. 4.30, а). Бит ECговорит о том, шифруется ли поле данных. Поле Типуказывает тип кадра (в частности, сообщает о том, пакуется ли кадр и есть ли фрагментация). Поле CIуказывает на наличие либо отсутствие поля финальной контрольной суммы. Поле EKсообщает, какой из ключей шифрования используется (если он вообще используется). В поле Длинасодержится информация о полной длине кадра, включая заголовок. Идентификатор соединения сообщает, какому из соединений принадлежит кадр. В конце заголовка имеется поле Контрольная сумма заголовка, значение которого вычисляется с помощью полинома х8 + х2 + x+ 1.

Рис. 4.30. Кадр: а — обычный; б — запроса канала

В протоколе 802.16 имеется много типов кадров. На рис. 4.33, б показан пример кадра запроса канала. Он начинается с единичного, а не нулевого бита и в целом напоминает заголовок обычного кадра, за исключением второго и третьего байтов, которые составляют 16-битное число, говорящее о требуемой полосе для передачи соответствующего числа байт. В кадре запроса канала отсутствует поле данных, нет и контрольной суммы всего кадра.

Можно долго говорить о стандарте 802.16, но все-таки не здесь. За дополнительной информацией обращайтесь, пожалуйста, к официальному описанию стандарта IEEE802.16-2009.

4.6. Bluetooth

В 1994 году компания Л. М. Эриксона (L. M. Ericsson) заинтересовалась вопросом беспроводной связи между мобильными телефонами и другими устройствами (например, портативными компьютерами). Совместно с четырьмя другими небезызвестными компаниями (IBM, Intel, Nokia и Toshiba) в 1998 году была сформирована специальная группа (SIG — Special Interest Group, то есть консорциум), которая занялась развитием стандарта беспроводного соединения вычислительных устройств и устройств связи, а также созданием аксессуаров, использующих недорогие маломощные радиоустройства небольшого радиуса действия. Проект был назван Bluetooth («Синий зуб») в честь великого короля викингов по имени Гаральд Синий Зуб II (940—981), который объединил (читай, завоевал) Данию и Норвегию. Ну да, он тоже сделал это без помощи проводов.

Bluetooth 1.0 появился в июле 1999 года, и с тех пор SIG никогда не оглядывалась назад. Теперь всевозможные потребительские электронные устройства используют Bluetooth — от мобильных телефонов и ноутбуков до наушников, принтеров, клавиатур, мышей, игровых приставок, часов, аудиоплееров, навигационных устройств и т. д. Протоколы Bluetooth позволяют этим устройствам находить друг друга и соединяться с помощью действия, называемого сопряжение (pairing), и затем надежно передавать данные.

Протоколы в течение прошедшего десятилетия также развивались. После того как стабилизировались начальные протоколы, в 2004 году к Bluetooth 2.0 были добавлены более высокие скорости передачи данных. Версия Bluetooth 3.0 2009 года может использоваться для сопряжения устройств в комбинации с 802.11 для высокоскоростной передачи данных. Версия 4.0 от декабря 2009 года определила работу с низким энергопотреблением. Это будет удобно для людей, которые не хотят регулярно менять батареи во всех устройствах в доме. Ниже мы опишем основные аспекты Bluetooth.

4.6.1. Архитектура Bluetooth

Начнем изучение системы Bluetooth с краткого обзора того, из чего она состоит и для чего предназначена. Основу Bluetooth составляет пикосеть (piconet), состоящая из одного главного узла и нескольких (до семи) подчиненных узлов, расположенных в радиусе 10 метров. В одной и той же комнате, если она достаточно большая, могут располагаться несколько пикосетей. Более того, они могут даже связываться друг с другом посредством моста (специального узла), как показано на рис. 4.31. Несколько объединенных вместе пикосетей составляют рассеянную сеть (scatternet).

Рис. 4.31. Две пикосети могут, соединившись, сформировать рассеянную сеть

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

Такое решение с главным и подчиненным узлом оказалось очень простым и дешевым в реализации (вся микросхема Bluetooth стоит менее $5). Поскольку этого и до-

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

4.6.2. Приложения Bluetooth

Большинство сетевых протоколов просто предоставляют каналы связи между коммуникационными единицами и оставляют прикладное использование этих каналов на усмотрение разработчиков. Например, в стандарте 802.11 ничего не говорится о том, что пользователи должны использовать свои ноутбуки для чтения электронной почты, работы в Интернете и т. п. В противоположность этому, Bluetooth специфицирует отдельные поддерживаемые приложения и для каждого из них предоставляет свой набор протоколов. На момент написания данного раздела было 25 таких приложений, называемых профилями (profiles). К сожалению, это приводит к сильному усложнению системы. Мы опустим многие детали в нашем описании, но коротко рассмотрим профили, чтобы увидеть, что группа Bluetooth пыталась достичь.

Шесть профилей предназначены для различного использования аудио и видео. Например, профиль intercom позволяет двум телефонам соединяться друг с другом наподобие раций. Профили наушников и устройств hands-free и обеспечивают этим устройствам связь с базовой станцией. Это удобно, например, при управлении автомобилем.

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

Профиль HID предназначен для устройств взаимодействия с человеком — соединения с компьютером клавиатур и мышей. Другие профили позволяют мобильному телефону или другому компьютеру получать изображение от камеры или посылать изображения принтеру. Возможно, более интересен профиль, позволяющий использовать мобильный телефон в качестве пульта дистанционного управления для телевизора (с поддержкой Bluetooth).

Следующая группа профилей имеет отношение к сетям. Профиль доступа к ЛВС позволяет устройству Bluetooth подсоединиться к сети непосредственно или получить удаленный доступ к сети, как и в 802.11, через точку доступа. Профиль удаленного доступа (dail-up networking) был, собственно говоря, тем, ради чего изначально был задуман весь проект. Он позволяет ноутбуку соединяться с мобильным телефоном, имеющим встроенный модем, без использования проводов.

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

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

Неужели действительно так необходимо было подробно описывать в стандарте все приложения и предоставлять наборы протоколов для каждого из них? Может быть и нет, но было создано довольно много рабочих групп, занимавшихся различными аспектами применения системы. Каждая рабочая группа разработала свой профиль. Считайте это демонстрацией закона Конвея в действии. (В апреле 1968 года в журнале Datamation была опубликована статья Мелвина Конвея (Melvin Conway), в которой утверждалось, что если поручить написание компилятора n программистам, то получится n-проходный компилятор. В более общем виде эта мысль звучит так: структура программного обеспечения отражает структуру группы разработчиков.) Наверное, можно было обойтись не 25, а двумя наборами протоколов — один для передачи файлов и один для передачи данных в реальном масштабе времени.

4.6.3. Bluetooth: набор протоколов

Стандарт Bluetooth включает в себя множество протоколов, довольно свободно разбитых на уровни, как показано на рис. 4.32. Структура на первый взгляд не следует ни модели OSI, ни TCP/IP, ни 802, ни какой-либо другой известной модели.

В самом низу находится физический (радиотехнический) уровень, который вполне соответствует моделям OSI и 802. На нем описывается радиосвязь и применяемые методы модуляции. Многое здесь направлено на то, чтобы сделать систему как можно дешевле и доступнее массовому покупателю.

Уровень управления каналом связи (прямой передачи) чем-то напоминает подуровень MAC, но включает в себя и некоторые элементы физического уровня. Здесь описывается то, как главный узел управляет временными интервалами и как эти интервалы группируются в кадры.

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

Протокол канального уровня — это L2CAP (Logical Link Control and Adaptation Protocol — протокол управления логическими каналами и согласования). Он собирает сообщения переменной длины и при необходимости обеспечивает надежность. L2CAP используется многими протоколами, в том числе и двумя описанными ранее служебными протоколами.

Протокол обнаружения сервисов используется для определения местонахождения служб в пределах сети. Протокол RFcomm эмулирует работу стандартного последо-

вательного порта ПК, к которому обычно подключаются клавиатура, мышь, модем и другие устройства.

Рис. 4.32. Архитектура протоколов Bluetooth: версия 802.15

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

В следующих разделах мы рассмотрим уровень радиосвязи и различные протоколы канального уровня Bluetooth, поскольку они пусть грубо, но все-таки соответствуют физическому уровню и подуровню MAC в других стеках протоколов, которые мы изучили ранее.

4.6.4. Bluetooth: уровень радиосвязи

Уровень радиосвязи переносит информацию бит за битом от главного узла к подчиненным и обратно. Это маломощная приемопередающая система с радиусом действия порядка 10 метров. Она работает в ISM диапазоне 2,4 ГГц, как и 802.11. Диапазон разделен на 79 каналов по 1 МГц в каждом. Чтобы сосуществовать с другими сетями, использующими ISM диапазон, применяется расширенный спектр со скачкообразной перестройкой частоты. Возможно до 1600 скачков частоты в секунду, длительность одного временного интервала (слота или такта) — 625 мкс. Все узлы пикосетей перестраивают частоты одновременно, в соответствии с синхронизацией тактов и псевдослучайной последовательностью скачков, генерируемой главным узлом.

К сожалению, оказалось, что ранние версии Bluetooth и 802.11 интерферируют так, что нарушают передачи друг друга. Некоторые компании отреагировали на это отказом от Bluetooth в целом, но, в конечном счете, техническое решение было найдено. Оно

заключалось в том, чтобы адаптировать последовательность скачков для исключения каналов, на которых есть другие радиосигналы. Этот процесс, названный адаптивной перестройкой рабочей частоты (adaptive frequency hopping), уменьшает помехи.

Для отправки бит по каналу используются три формы модуляции. Базовая схема состоит в использовании кодирования со сдвигом частоты, чтобы посылать 1-битовый символ каждую микросекунду, что дает общую скорость данных 1 Мбит/с. Большие скорости появились начиная с версии Bluetooth 2.0. Эти скорости используют кодирование со сдвигом фазы, чтобы послать или 2 или 3 бита за символ, для достижения общей скорости данных 2 или 3 Мбит/с. Такие более высокие скорости применяются только для кадров, содержащих данные.

4.6.5. Bluetooth: уровень немодулированной передачи

Уровень немодулированной передачи (управления каналом связи) — это наиболее близкий к MAC-подуровню элемент иерархии Bluetooth. Он трансформирует простой поток бит в кадры и определяет некоторые ключевые форматы. В простейшем случае главный узел каждой пикосети выдает последовательности временных интервалов по 625 мкс, причем передача данных со стороны главного узла начинается в четных тактах, а со стороны подчиненных узлов — в нечетных. Эта схема, по сути дела, традиционное временное уплотнение, в котором главная сторона получает одну половину временных интервалов, а подчиненные делят между собой вторую. Кадры могут быть длиной 1, 3 или 5 тактов.

В каждом кадре уходит 126 служебных бит на код доступа и заголовок, кроме того, время установки занимает 250—260 мкс на переключение частоты, чтобы позволить недорогим радиосхемам становиться устойчивыми. Полезные данные кадра могут быть для конфиденциальности зашифрованы с помощью ключа, который выбирается, когда ведущее устройство соединяется с ведомым. Переключения частоты происходят только между кадрами, но не во время передачи кадра. В результате передача 5-тактового кадра намного более эффективна чем 1-тактового, потому что при тех же служебных расходах посылается больше данных.

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

Прежде чем будет использоваться соединение, два устройства проходят процедуру сопряжения. Более старый метод сопряжения — оба устройства должны быть сконфигурированы с одним и тем же PIN-кодом из четырех цифр (PIN, Personal Identification Number — личный идентификационный номер). Соответствие PIN позволяет устройству знать, что оно соединилось с нужным удаленным устройством. Однако лишенные воображения пользователи и использование значений по умолчанию устройств, таких как «0000» и «1234» ведут к тому, что этот метод на практике обеспечивает не очень высокий уровень безопасности.

Новый безопасный простой метод сопряжения (secure simple pairing) позволяет пользователям подтвердить, что оба устройства показывают один и тот же ключ, или видеть ключ на одном устройстве и ввести его на втором. Этот метод более безопасен, потому что пользователи не должны выбирать или устанавливать PIN. Они просто подтверждают ключ, более длинный и произведенный устройством. Конечно, этот метод не может использоваться на некоторых устройствах с ограниченным вводом/ выводом, таких как беспроводные гарнитуры.

Когда сопряжение завершено, протокол устанавливает соединения. Существует два основных типа соединений. Первый вид называется SCO (Synchronous Connection Oriented синхронный с установлением связи). Он предназначен для передачи данных в реальном масштабе времени — это требуется, например, при телефонных разговорах. Такой тип канала получает фиксированный временной интервал для передачи в каждом из направлений. У подчиненного узла может быть до трех соединений типа SCO с главным узлом, каждое из которых представляет собой аудиоканал PCM с пропускной способностью 64 000 бит/с. Из-за критичной ко времени передачи природы SCO кадры, переданные по данному типу канала, никогда не пересылаются заново. Вместо этого может быть использована прямая коррекция ошибок, обеспечивающая более надежное соединение.

Другой тип соединения называется ACL (Asynchronous Connectionless асинхронный без установления связи). Этот тип связи используется для коммутации пакетов данных, которые могут появиться в произвольный момент времени. Трафик ACL доставляется по принципу максимально прилагаемых усилий для обеспечения сервиса. Никаких гарантий не дается. Кадры могут теряться и пересылаться повторно. У подчиненного узла может быть только одно ACL-соединение со своим главным узлом.

Данные, отправленные по ACL-соединению, появляются с уровня L2CAP. Этот уровень выполняет четыре основные функции. Во-первых, он принимает пакеты размером до 64 Кбайт с верхних уровней и разбивает их на кадры для передачи по физическому каналу. На противоположном конце этот же уровень используется для обратного действия — объединения кадров в пакеты.

Во-вторых, L2CAP занимается мультиплексированием и демультиплексированием множества источников пакетов. После сборки пакета он определяет, куда следует направить пакет (например, протоколу RFcomm или протоколу обнаружения сервисов).

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

4.6.6. Bluetooth: структура кадра

Существует несколько форматов кадров Bluetooth, наиболее важный из которых показан в двух формах на рис. 4.33. В начале кадра указывается код доступа, который обычно служит идентификатором главного узла. Это позволяет двум главным узлам, которые расположены достаточно близко, чтобы «слышать» друг друга, различать, кому из них предназначаются данные. Затем следует заголовок из 54 бит, в котором содержатся поля, характерные для кадра подуровня MAC. Если кадр отправляется с базовой скоростью, далее расположено поле данных. Его размер ограничен 2744 битами (для передачи за пять тактов). Если кадр имеет длину, соответствующую одному тактовому интервалу, то формат остается таким же, с той разницей, что поле данных в этом случае составляет 240 бит.

Рис. 4.33. Типичный информационный кадр Bluetooth: а — на базовой скорости; б — на увеличенной скорости

Если кадр посылается на увеличенной скорости, часть данных может быть в два или три раза больше, потому что каждый символ переносит 2 или 3 бита вместо одного бита. Этим данным предшествуют защитный интервал и образец синхронизации, который используется, чтобы переключиться на более высокую скорость передачи данных. Таким образом, код доступа и заголовок передаются на базовой скорости, и только часть данных передается на большей скорости. Кадры с большей скоростью заканчиваются короткой меткой конца.

Рассмотрим, из чего состоит обычный заголовок кадра. Поле Адрес идентифицирует одно из восьми устройств, которому предназначена информация. Поле Тип определяет тип передаваемого кадра (ACL, SCO, опрос или пустой кадр), метод коррекции ошибок и количество временных интервалов, из которых состоит кадр. Бит F (Flow — поток) выставляется подчиненным узлом и сообщает о том, что его буфер заполнен. Этот бит обеспечивает примитивную форму управления потоком. Бит A (Acknowledgement — подтверждение) представляет собой подтверждение (ACK), отсылаемое заодно с кадром. Бит S (Sequence — последовательность) используется для нумерации кадров, что позволяет обнаруживать повторные передачи. Это протокол с ожиданием, поэтому одного бита действительно оказывается достаточно. Далее следует 8-битная контрольная сумма заголовка. Весь 18-битный заголовок кадра повторяется трижды, что в итоге составляет 54 бита, как показано на рис. 4.33. На принимающей стороне несложная схема анализирует все три копии каждого бита. Если они совпадают, бит принимается таким, какой он есть. В противном случае все решает большинство. Как видите, на передачу 10 бит тратится в данном случае 54 бита. Причина очень проста: за все нужно платить. За обеспечение передачи данных с помощью дешевых, маломощных устройств (2,5 мВт) с невысокими вычислительными способностями приходится платить большой избыточностью.

Для ACL- и SCO-кадров применяются различные форматы поля данных. В кадрах SCO с базовой скоростью кадры устроены просто: длина поля данных всегда равна 240 бит. Возможны три варианта: 80, 160 или 240 бит полезной информации. При этом оставшиеся биты поля данных используются для исправления ошибок. В самой надежной версии (80 бит полезной информации) одно и то же содержимое повторяется три раза (что и составляет 240 бит), как и в заголовке кадра.

Мы можем вычислить емкость следующим образом. Поскольку подчиненные узлы могут использовать только нечетные временные интервалы, им достается 800 интервалов в секунду. Столько же получает и главный узел. При 80 битах полезных данных, передающихся в одном кадре, емкость канала подчиненного узла равна 64 000 бит/с. Этому же значению равна и емкость канала главного узла. Этого как раз хватает для организации полнодуплексного PCM-канала голосовой связи (именно поэтому 1600 скачков в секунду было выбрано в качестве скорости перестройки частот). Все эти цифры говорят о том, что полнодуплексный канал со скоростью 64 000 бит/с в каждую сторону при самом надежном способе передачи информации вполне устраивает пикосеть, невзирая на то, что суммарная скорость передачи данных на физическом уровне равна 1 Мбит/с.

Эффективность 13% — результат расходов 41% емкости на время стабилизации, 20% на заголовки, и 26% на повторном кодировании. Этот недостаток выделяет значение увеличенных скоростей и кадров более чем из одного слота.

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

4.7. RFID

Мы уже рассмотрели схемы MAC от локальных до городских и персональных вычислительных сетей. В качестве последнего примера мы изучим категорию беспроводных устройств «низшего класса», которые, возможно, не признаются формирующими компьютерные сети: это RFID (Radio Frequency Identification радиочастотная идентификация) метки и считыватели, которые мы описали в разделе 1.5.4.

Технология RFID существует во многих формах, используемых в смарткартах, имплантантах для домашних животных, паспортах, библиотечных книгах и пр. Форма, которую мы рассмотрим, была развита при разработках EPC (Electronic Product Code электронный код товара), которые начинались в Auto-ID Центре в Массачусетском технологическом институте в 1999 году. EPC — это замена штрихкода, которая может нести большее количество информации и считываться с помощью электроники на расстоянии до 10 м, даже не в прямой видимости. Эта технология отличается, например, от RFID-используемой в паспортах, которые должны быть помещены достаточно близко к считывателю для получения информации. Способность общаться на расстоянии делает EPC более значимым для нашего изучения.

Организация EPCglobal была создана в 2003 году, чтобы коммерциализировать развитую Auto-ID Центром технологию RFID. Их усилия получили развитие в 2005 году, когда компания Walmart потребовала от 100 своих крупнейших поставщиков маркировать все поставки метками RFID. Широкому распространению технологии препятствовала трудность конкуренции с дешевыми печатаемыми штрихкодами, но появились новые сферы использования, например водительские права. Мы опишем второе поколение этой технологии, которую неофициально называют EPC Gen 2 (EPCglobal, 2008).

4.7.1. Архитектура EPC Gen 2

Архитектура EPC Gen 2 сети RFID показана на рис. 4.34. Она имеет два ключевых компонента: метки (теги) и считыватели. Метки RFID — маленькие, недорогие устройства, имеющие уникальный 96-битовый идентификатор EPC и небольшое количество памяти, запись и чтение которой может производиться RFID-считывателем. Память может использоваться для записи истории местоположения элемента, например, когда он движется по системе поставок.

Часто метки похожи на этикетки, которые могут быть помещены, например, на джинсы на полках в магазине. Большая часть этикетки занята антенной, которая на ней напечатана. Крошечная точка в середине — интегральная схема RFID. Другой вариант — метка RFID может быть внедрена в объект, например в водительские права. В обоих случаях метки не содержат никакой батареи и должны получать энергию для работы из радиопередачи ближайшего RFID-считывателя. Этот вид меток называют метки «Class 1», чтобы отличить их от меток с большими возможностями, у которых есть батареи.

Рис. 4.34. Архитектура RFID

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

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

4.7.2. Физический уровень EPC Gen 2

Физический уровень определяет, как биты пересылаются между метками и RFID-считывателем. В основном используются методы отправки беспроводных сигналов, которые мы видели ранее. В США обмен происходит в нелицензированном диапазоне ISM полосы 902-928 МГц. Эта полоса относится к диапазону UHF (УВЧ), поэтому соответствующие метки называют UHF-метками RFID. Считыватель выполняет скачки частоты по крайней мере каждые 400 мс, чтобы распространить сигнал по каналу, ограничить помехи и выполнить нормативные требования. Чтобы закодировать биты, считыватель и метки используют формы амплитудной модуляции ASK, которую мы описали в разделе 2.5.2. Они посылают биты по очереди, таким образом, канал — полудуплексный.

Имеется два основных отличия от других физических уровней, которые мы изучили. Прежде всего, сигнал всегда передает считыватель, независимо от того, осуществляет ли коммуникацию он или метка. Естественно, считыватель передает сигнал, чтобы послать биты в метки. А для того чтобы метки послали биты считывателю, он передает сигнал фиксированной несущей, который не переносит битов. Метки собирают этот сигнал для получения энергии, которая необходима для их работы; таким образом, метка не могла бы передавать первой. Чтобы послать данные, метка меняет свое поведение — отражает ли она сигнал от считывателя, как радарный сигнал, возвращающийся от цели, или поглощает его.

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

Второе отличие в том, что применяются очень простые формы модуляции, так чтобы они могли быть осуществлены меткой, которая работает на очень небольшой мощность и очень дешево стоит. Чтобы послать данные в метки, считыватель использует два уровня амплитуды. Биты 0 или 1 определяются в зависимости от того, сколько времени считыватель ждет перед периодом низкой мощности. Метка измеряет время между периодами низкой мощности и сравнивает это время с измеренной во время преамбулы. Как показано на рис. 4.35, 1 более длинный, чем 0.

Ответы метки состоят из изменения состояния его обратного рассеяния через фиксированные интервалы, что создает серию импульсов в сигнале. Чтобы закодировать каждый 0 или 1, может использоваться от одного до восьми периодов импульса, в зависимости от потребности в надежности. 1 имеют меньше переходов, чем 0, как показано на рис. 4.35 в примере кодирования с периодом в два импульса.

Рис. 4.35. Сигналы считывателя и сигналы обратного рассеяния от метки

4.7.3. Уровень идентификации метки EPC Gen 2

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

В этой главе мы видели уже много способов, относящихся к задаче множественного доступа. Самый близкий к данной ситуации, когда метки не могут слышать друг друга, протокол дискретная ALOHA, один из самых первых изученных нами. Этот протокол адаптирован к использованию в Gen 2 RFID.

Последовательность сообщений, используемых, чтобы идентифицировать тег, показана на рис. 4.36. В первый слот (слот 0) считыватель посылает сообщение Query, чтобы запустить процесс. Каждое сообщение QRepeat подается в следующий слот. Считыватель сообщает меткам диапазон слотов, по которым можно рандомизировать передачи. Использовать диапазон необходимо, потому что считыватель синхронизирует метки, когда запускает процесс; в отличие от станций на Ethernet, метки не просыпаются с сообщением в выбранное время.

Рис. 4.36. Пример обмена сообщениями для идентификации метки

Метки выбирают случайный слот, в котором можно отвечать. На рис. 4.36 метка отвечает в слоте 2. Однако отвечая, метки не сразу посылают свои идентификаторы. Вместо этого они посылают короткое 16-битовое случайное число в сообщении RN16. Если нет коллизий, считыватель получает это сообщение и посылает собственное сообщение ACK. На этом этапе метка получает слот и посылает свой идентификатор EPC.

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

Ключевая проблема для считывателя — определить такое количество слотов, чтобы избежать коллизий, но не использовать слишком много слотов, отчего пострадает производительность. Это согласование похоже на двойную экспоненциальную выдержку в Ethernet. Если считыватель видит слишком много слотов без ответов или слишком много слотов с коллизиями, он может послать сообщение QAdjust, чтобы уменьшить или увеличить диапазон слотов, по которым отвечают метки.

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

4.7.4. Форматы сообщения идентификации метки

Формат сообщения запроса показан на рис. 4.40 как пример сообщения от считывателя к метке. Сообщение компактно, потому что скорости передачи информации ограничены, от 27 до 128 Кбит/с. Поле команды содержит код 1000, что идентифицирует сообщение как Query.

Рис. 4.37. Формат сообщения Query

Следующие флаги, DR, M и TR, определяют параметры физического уровня для передачи считывателя и ответов метки. Например, скорость ответа может быть установлена между 5 и 640 Кбит/с. Мы пропустим подробности этих флагов.

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

Затем идет самый важный параметр этой команды, Q. Это поле определяет диапазон слотов, по которым ответят метки, от 0 до 2Q - 1. Наконец, имеется CRC, чтобы защитить поля сообщения. Она занимает 5 бит, что короче, чем большинство CRC, которые мы рассматривали, но и сообщение Query намного короче, чем большинство пакетов.

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

Первоначально метки применялись только в целях идентификации. Однако со временем они выросли и стали напоминать очень маленькие компьютеры. У некоторых исследовательских меток есть датчики, и они в состоянии выполнить маленькие программы, чтобы собрать и обработать данные (Sample и др., 2008). Один из взглядов на эту технологию — «Интернет вещей», который присоединяет объекты материального мира к Интернету (Welboume и др., 2009; Gershenfeld и др., 2004).

4.8. Коммутация на канальном уровне

У многих организаций имеется по нескольку локальных сетей, которые необходимо объединять между собой. Может быть, удобно объединить эти сети в одну большую локальную сеть? Это можно сделать с помощью специальных устройств, называемых мостами (bridges). Коммутаторы Ethernet, которые мы описали в разделе 4.3.4, — это современное название мостов; они обеспечивают функциональность, которая идет вне классического Ethernet и концентраторов Ethernet, чтобы облегчить соединение нескольких ЛВС в большую и более быструю сеть. Мы будем использовать термины «мост» и «коммутатор» попеременно.

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

В этом разделе мы рассмотрим работу мостов и соединение с их помощью нескольких физических локальных сетей в одну логическую локальную сеть. Кроме того, мы рассмотрим противоположную задачу — разделение одной физической локальной сети на несколько логических локальных сетей, так называемых виртуальных ЛВС (ВЛВС - VLAN, Virtual LAN). Обе технологии предоставляют полезную гибкость в управлении сетями. Подробную информацию о мостах, коммутаторах и близких темах можно найти у (Seifert и Edwards, 2008) и (Perlman, 2000).

4.8.1. Применение мостов

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

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

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

Даже если кабели легко проложить, есть пределы их возможной длины (например, 200 м для витой пары Gigabit Ethernet). Сеть не будет работать с более длинными кабелями из-за чрезмерного ослабления сигнала или задержки туда и обратно. Единственное решение состоит в том, чтобы разделить ЛВС и установить мосты, соединяющие ее части, чтобы увеличить полную физическую дистанцию, которая может быть преодолена.

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

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

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

Все это должно происходить без каких-либо изменений аппаратуры, настроек адресов коммутатора, программного обеспечения или конфигурационных таблиц и т. п. Кроме того, работа существующих ЛВС вообще не должна быть затронута мостами. Что касается затронутых станций, не должно быть никакого заметного различия, являются ли они частью ЛВС с мостами или нет. Должно быть столь же легко переместить станции в ЛВС с мостами, как и в одиночной ЛВС.

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

4.8.2. Обучаемые мосты

Топология двух ЛВС, соединенных мостом, показана на рис. 4.38 для двух вариантов. Слева, к двум многоточечным ЛВС, таким как классический Ethernet, присоединяется специальная станция — мост, который сидит на обеих ЛВС. Справа объединены ЛВС с двухточечными кабелями, включая один концентратор. Мосты — устройства, к которым присоединены станции и концентратор. Если технология ЛВС — Ethernet, мосты более известны под названием коммутаторы.

Рис. 4.38. Мосты: а — мост, соединяющий две многоточечные ЛВС; б — мосты (и концентратор), соединяющие семь станций по двухточеной схеме

Мосты были развиты, когда использовался классический Ethernet, поэтому их часто показывают в топологии с многоточечными кабелями, как на рис. 4.38, а. Однако все топологии, которые можно встретить сейчас, состоят из двухточечных кабелей и коммутаторов. Мосты работают одинаково в обеих ситуациях. Все станции, присоединенные к тому же самому порту на мосту, принадлежат тому же самому домену коллизий, который отличается от доменов коллизий других портов. Если есть больше, чем одна станция, как в классическом Ethernet, концентратор или полудуплексный канал, для отправки кадров используется протокол CSMA/CD.

Однако есть различие в том, как устроены соединенные ЛВС. Чтобы соединить многоточечные ЛВС, мост добавлен как новая станция в каждой из них, как показано на рис. 4.38, а. Чтобы соединить двухточечные ЛВС, концентраторы или соединены с мостом, или, предпочтительно, заменены мостом, чтобы увеличить производительность. На рис. 4.38, б мосты заменили все, кроме одного концентратора.

К одному мосту также могут быть присоединены различные виды кабелей. Например, кабель, соединяющий B1 с мостом B2 на рис. 4.38, б, мог бы быть длинным оптоволоконным каналом, в то время как кабель, соединяющий мосты со станциями, мог бы быть короткой линией на витой паре. Такое расположение полезно для соединения ЛВС в различных зданиях.

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

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

Например, рассмотрим топологию на рис. 4.38, а. Если станция A пошлет кадр станции B, то мост B1 получит кадр на порту 1. От этого кадра можно немедленно отказаться без дальнейшей суматохи, потому что он уже находится на правильном порту. Теперь предположим в топологии на рис. 4.38, б, что A посылает кадр D. Мост В1, получит кадр на порту 1 и выведет его на порт 4. Затем мост В2 получит кадр на своем порту 4 и выведет его на своем порту 1.

Простой способ реализовать эту схему состоит в том, чтобы мост имел большую (хэш) таблицу. В таблице могут быть перечислены все возможные места назначения и к какому порту каждое относится. Например, на рис. 4.38, б таблица в B1 перечисляла бы D как принадлежащий порту 4, так весь B1 знал бы, в какой порт отправить кадры для D. Тогда, фактически, дальнейшая пересылка произойдет позже, когда достигший B2 кадр не представляет интереса для B1.

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

Для обучения прозрачных мостов используется алгоритм так называемого противоточного обучения (backward learning). Как уже упоминалось выше, мосты работают в неразборчивом режиме, поэтому они видят все кадры, посылаемые во всех их портах. Просматривая адреса отправителей, они могут определить, какая станция доступна по какому порту. Например, если мост В1 на рис. 4.38, б видит кадр, приходящий к нему на порт 3 от станции C, то он понимает, что станция C достижима через порт 3, и делает соответствующую запись в своей таблице. Поэтому любой последующий кадр, адресованный станции C и приходящий в В1 по любому другому порту, будет переправляться в порт 3.

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

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

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

1.    Если порт источника и порт для адреса назначения совпадают, кадр игнорируется.

2.    Если порт источника и порт для адреса назначения различаются, кадр переправляется в порт назначения.

3. Если порт назначения неизвестен, используется алгоритм заливки, и кадр пересылается во все порты, кроме порта источника.

Вы могли бы задаться вопросом, может ли первый случай произойти с двухточечными линиями. Ответ — это может произойти, если для соединения группы компьютеров с мостом используются концентраторы. Пример показан на рис. 4.38, б, где станции E и F соединены с концентратором H1, который, в свою очередь, соединен с мостом B2. Если E пошлет кадр F, то концентратор передаст его B2, так же как и F. Именно это делают концентраторы — они связывают все порты вместе так, чтобы кадр, введенный на одном порту, просто выводится на всех других портах. Кадр достигнет B2 на порту 4, который уже является правильным выходным портом, чтобы достигнуть места назначения. Мост B2 должен просто отказаться от кадра.

Поскольку этот алгоритм должен быть применен к каждому прибывающему кадру, обычно он осуществляется специальными чипами СБИС. Чип производит поиск и обновляет записи таблицы за несколько микросекунд. Поскольку мосты смотрят только на MAC адреса, чтобы решить, как отправить кадры, возможно начать отправку, как только появилось поле заголовка назначения, до того как дошла остальная часть кадра (конечно, если выходная линия доступна). Эта схема сокращает время ожидания прохождения через мост, а также количество кадров, которые мост должен быть в состоянии буферизовать. Такой способ называют коммутация без буферизации пакетов (cut-through switching) или маршрутизация способом коммутации каналов (wormhole routing), и обычно он реализуется аппаратными средствами.

Мы можем посмотреть на работу моста с точки зрения стека протоколов, чтобы понять, что это означает быть устройством уровня канала. Рассмотрим кадр, посланный от станции А к станции D в конфигурации на рис. 4.38, а, в которой ЛВС — Ethernet. Кадр пройдет через один мост. Вид стека протокола обработки показан на рис. 4.39.

Пакет прибывает из более высокого уровня и спускается на уровень MAC Ethernet. Он приобретает заголовок Ethernet (а также метку конца, не показанную на рисунке). Этот кадр передается физическому уровню, выходит по кабелю и принимается мостом.

Рис. 4.39. Протоколы, обрабатываемые на мосту

В мосте кадр передается с физического уровня на уровень MAC Ethernet. Этот уровень расширяет обработку по сравнению с уровнем MAC Ethernet на станции. Он передает на ретранслятор, все еще в пределах уровня MAC. Функция ретрансляции моста использует только заголовок MAC Ethernet, чтобы определить, как обработать кадр. В нашем случае он передает кадр тому порту уровня MAC Ethernet, который используется для достижения станции D, и кадр продолжает свой путь.

В общем случае, ретрансляторы на некотором уровне могут переписать заголовки для этого уровня. ВЛВС вскоре обеспечит пример. Мост ни в коем случае не должен смотреть внутрь кадра и узнавать, что он переносит IP-пакет; это не важно для обработки мостом и нарушило бы иерархическое представление протокола. Также отметьте, что мост, имеющий k портов, будет иметь k экземпляров MAC-уровней и физических уровней. В нашем простом примере k = 2.

4.8.3. Мосты связующего дерева

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

Рис. 4.40. Мосты с двумя параллельными соединениями

Такое решение, впрочем, создает некоторые дополнительные проблемы, поскольку в топологии образуются кольца. В качестве примера, иллюстрирующего указанные проблемы, рассмотрим кадр, отправленный А с ранее неизвестным адресом назначения (рис. 4.40). Каждый мост, действуя по обычным правилам обработки кадров с неизвестным получателем, использует метод заливки. В данном примере это означает, что кадр из А попадает к мосту В1, F0 . Мост посылает копии этого кадра во все остальные свои порты. Мы рассмотрим только порты, соединяющие В1 и В2 (хотя кадр будет послан и в другие). Так как из В1 в В2 есть два соединения, в В2 попадут две копии кадра. Они показаны на рис. 4.40 как F1 и F2 .

Вскоре после этого мост В1 получает эти кадры. Разумеется, он не знает (и не может знать), что это копии одного кадра, а не два разных кадра, посланных один за другим. Поэтому мост В2 отправляет копии кадра F1 во все свои порты. Так возникают F3 и F4, которые по двум соединениям отправляются обратно в В1. Мост В1 видит два новых кадра с неизвестным адресом назначения и копирует их снова. Этот цикл продолжается вечно.

Решение данной проблемы заключается в установлении связи между мостами и наложении на реальную топологию сети связующего дерева (spanning tree), до-

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

Например, на рис. 4.41 показаны пять мостов, которые связаны и имеют соединенные с ними станции. Каждая станция соединяется только с одним мостом. Есть некоторые избыточные соединения между мостами, так что если будут использоваться все соединения, кадры будут отправлены в циклы.

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

Рис. 4.41. Связующее дерево, соединяющее пять мостов. Пунктирными линиями показаны соединения, которые не входят в связующее дерево

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

Мосты должны сначала выбрать один мост, который будет корнем связующего дерева. Чтобы сделать этот выбор, каждый из них включает в конфигурационное сообщение идентификатор, основанный на своем MAC-адресе, так же как идентификатор моста, который он предполагает корнем. MAC-адреса установлены изготовителем и гарантировано уникальны во всем мире, что делает эти идентификаторы удобными и гарантированно разными. Мосты выбирают в качестве корня мост с наименьшим идентификатором. После обмена достаточным числом сообщений, чтобы распространить эту новость, все мосты договорятся, какой мост является корнем. На рис. 4.41 мост B1 имеет наименьший идентификатор и становится корнем.

Затем создается дерево кратчайших путей от корня до каждого моста. На рис. 4.41 мосты B2 и B3 могут быть достигнуты от моста B1 непосредственно, за один шаг, который является кратчайшим путем. Мост B4 может быть достигнут за два шага, или через B2 или через B3. Чтобы разрубить этот узел, выбирается путь через мост с наименьшим идентификатором, таким образом, B4 будет достигнут через B2. Мост B5 может быть достигнут за два шага через B3.

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

Хотя дерево охватывает все мосты, но не все соединения (или даже мосты) обязательно присутствуют в дереве. Это происходит, потому что отключение портов ликвидирует некоторые соединения в сети, чтобы предотвратить появление циклов. Алгоритм построения дерева продолжает работать постоянно, обнаруживая изменения в топологии и обновляя структуру дерева.

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

I think that I shall never see A graph more lovely than a tree.

A tree whose crucial property Is loop-free connectivity.

A tree which must be sure to span.

So packets can reach every LAN.

First the Root must be selected By ID it is elected.

Least cost paths from Root are traced In the tree these paths are placed.

A mesh is made by folks like me Then bridges find a spanning tree.

Алгоритм связующего дерева стандартизован как IEEE 802.1D и используется уже много лет. В 2001 году он был пересмотрен для более быстрого нахождения нового связующего дерева после изменения топологии. Для более подробного рассмотрения мостов см. Perlman (2000).

4.8.4. Повторители, концентраторы, мосты, коммутаторы, маршрутизаторы и шлюзы

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

Чтобы понять, как работают эти устройства, надо осознать, что они работают на разных уровнях, как показано на рис. 4.42, а. Уровень имеет значение, поскольку от этого зависит, какую часть информации устройство использует для маршрутизации. Типичный сценарий таков: у пользователя появляются какие-то данные, которые необходимо отправить на удаленную машину. Они передаются на транспортный уровень, который добавляет к ним свой заголовок (например, заголовок TCP) и передает результирующую единицу информации на сетевой уровень. Тот, в свою очередь, тоже добавляет свой заголовок, в результате чего формируется пакет сетевого уровня (например, IP-пакет). На рис. 4.42, б IP-пакет выделен серым цветом. Пакет отправляется на канальный уровень, где обрастает еще одним заголовком и контрольной суммой (CRC). Наконец, формируется кадр, который спускается на физический уровень и может быть передан, например, по ЛВС.

Рис. 4.42. Соответствие устройств уровням (а); кадры, пакеты и заголовки (б)

Приступим к рассмотрению коммутирующих устройств и взглянем на то, как они соотносятся с пакетами и кадрами. На самом нижнем, физическом уровне работают повторители. Это аналоговые устройства, к которым подсоединяются концы двух сегментов кабеля. Сигнал, появляющийся на одном из них, очищается, усиливается повторителем и выдается на второй. Повторители не знают слов «пакет», «кадр» или «заголовок». Они знают символы, кодирующие биты в напряжение. В классическом Ethernet, например, допускается установка четырех повторителей, что усилит сигнал, чтобы увеличить максимальную длину кабеля с 500 до 2500 м.

Теперь обратимся к концентраторам. Концентратор имеет несколько входов, объединяемых электрически. Кадры, прибывающие на какой-либо вход, передаются на все остальные линии. Если одновременно по разным линиям придут два кадра, они столкнутся, как в коаксиальном кабеле. Все линии, подсоединяемые к нему, должны работать с одинаковыми скоростями. Концентраторы отличаются от повторителей тем, что они обычно не усиливают входные сигналы, поскольку предназначены не

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

Перейдем теперь на канальный уровень. Здесь мы обнаружим мосты и коммутаторы. Только что мы как раз более или менее подробно обсуждали мосты, поэтому знаем, что мост соединяет две или более ЛВС. Как и в концентраторах, в современных мостах имеются несколько портов, рассчитанных обычно на от 4 и до 48 входящих линий определенного типа. В отличие от концентратора каждый порт изолирован, чтобы быть собственным доменом коллизий; если у порта есть полнодуплексная двухточечная линия, в алгоритме CSMA/CD нет необходимости. Когда прибывает кадр, мост извлекает из заголовка и анализирует адрес назначения, сопоставляя его с таблицей и определяя, куда этот кадр должен быть передан. Для Ethernet этот адрес — 48-битный адрес назначения (рис. 4.14). Мост только выдает кадр в нужный порт и может передавать несколько кадров одновременно.

Мосты предлагают намного лучшую производительность, чем концентраторы, а изоляция между портами моста также означает, что входные линии могут работать на различных скоростях, возможно даже с различными типами сетей. Типичный пример — мост с портами, которые соединяются с 10-, 100- и 1000-Мбит/с Ethernet. Буферизация в мосте необходима, чтобы принять кадр на одном порту и передать его на другой порт. Если кадры приходят быстрее, чем они могут быть повторно переданы, мост может исчерпать буферное пространство и начать отказываться от кадров. Например, если Gigabit Ethernet заливает биты в 10-Мбит/с Ethernet на большой скорости, мост должен будет буферизовать их, надеясь не исчерпать память. Эта проблема существует, даже если все порты работают на одной и той же скорости, потому что в данный порт назначения кадры могут быть посланы из нескольких портов.

Мосты первоначально предназначались для того, чтобы соединять различные виды ЛВС, например Ethernet и Token Ring. Однако из-за различий между ЛВС это никогда не работало хорошо. Различные форматы кадра требуют копирования и переформатирования, которое занимает время центрального процессора, требует нового вычисления контрольной суммы и добавляет возможность необнаруженных ошибок из-за плохих битов в памяти моста. Еще одна серьезная проблема без хорошего решения — различные максимальные длины кадра. Нужно стремиться избавиться от слишком длинных кадров. В первую очередь — для совместимости.

Двумя другими областями, где ЛВС могут отличаться, является безопасность и качество обслуживания. У некоторых ЛВС есть шифрование канального уровня, например у 802.11, у некоторых, например Ethernet, его нет. У некоторых ЛВС есть возможности для обеспечения качества обслуживания, такие как приоритеты, например у 802.11, у некоторых, например Ethernet, их нет. Следовательно, когда кадр должен быть передан между этими ЛВС, безопасность или качество обслуживания, ожидаемое отправителем, возможно, не может быть обеспечено. По всем этим причинам современные мосты обычно работают с сетями одного типа, а для присоединения к сетям различных типов используются маршрутизаторы, к которым мы скоро перейдем.

Коммутаторы — это другое название современных мостов. Различия больше связаны с маркетингом, чем с техническими особенностями, но есть несколько важных моментов. Мосты были разработаны, когда использовался классический Ethernet, таким образом, они имеют тенденцию присоединяться к относительно небольшому числу ЛВС, а значит, иметь относительно немного портов. Термин «коммутатор» более популярен в настоящее время. Кроме того, все современные системы используют двухточечные линии, такие как кабели витой пары, таким образом, отдельные компьютеры включаются непосредственно в коммутатор, и поэтому коммутатор будет стремиться иметь много портов. Наконец, «коммутатор» также используется в качестве общего термина. С мостом функциональность ясна. С другой стороны, «коммутатор» может относиться к коммутатору Ethernet или абсолютно другому виду устройства, которое принимает решения по перенаправлению, такому как телефонный коммутатор.

Итак, мы рассмотрели вкратце повторители и концентраторы, которые весьма сходны друг с другом, а также коммутаторы и мосты, которые еще более похожи. Теперь же мы перейдем к маршрутизаторам, которые резко отличаются от всего рассмотренного выше. Когда пакет прибывает на маршрутизатор, отрезаются заголовки и концевики кадров и остаются только поля данных (выделены серым на рис. 4.42), которые и передаются программному обеспечению маршрутизатора. Далее анализируется заголовок пакета и в соответствии с ним выбирается его дальнейший путь. Если это IP-пакет, то в заголовке будет содержаться 32-битный (IPv4) или 128-битный (IPv6), а не 48-битный IEEE 802 адрес. Программное обеспечение маршрутизатора не интересуется адресами кадров и даже не знает, откуда эти кадры взялись (то ли с ЛВС, то ли с двухточечной линии). Более подробно мы изучим маршрутизаторы и принципы маршрутизации в главе 5.

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

Наконец, шлюзы приложений уже работают с форматами и содержимым пакетов, занимаясь переформатированием на более высоком уровне. Например, шлюз e-mail может переводить электронные письма в формат SMS-сообщений для мобильных телефонов. Как и «коммутатор», «шлюз» — своего рода общий термин. Он относится к процессу пересылки, который выполняется в верхнем уровне.

4.8.5. Виртуальные локальные сети

На заре развития технологий локальных сетей толстые желтые провода опутали огромное количество офисов. Можно было подключить к сети каждый компьютер, мимо которого шел такой провод. Никто не задумывался над тем, к какой ЛВС подключен конкретный компьютер. Все люди из соседних офисов были подключены к одной сети, без учета того, насколько им это было нужно. «География» управляла корпоративными организационными структурами.

С появлением в 1990-е годы витых пар и концентраторов все изменилось. Из офисных зданий стали исчезать эти желтые провода, напоминающие садовые шланги, и им

на смену пришли витые пары, которые шли к щитам, висящим по концам коридоров (или в центральных машинных залах) и напичканным проводами, как показано на рис. 4.43. Если чиновник, ответственный за прокладку кабелей в здании, был способен смотреть в будущее, то устанавливались витые пары категории 5; если же он был крохобором, то использовались существующие (телефонные) витые пары категории 3, которые были заменены только с приходом сетей типа Fast Ethernet.

Рис. 4.43. Здание с централизованной проводкой с использованием концентратора и коммутатора

Сегодня кабели изменились, а концентраторы стали коммутаторами, но общая схема осталась прежней. Она позволяет настраивать локальные сети не физически, а логически. Если компании требовалось k ЛВС, она может приобрести k коммутаторов. Аккуратно собрав сеть (то есть вставив нужные соединители в нужные разъемы), можно было определить ее пользователей таким образом, чтобы это имело некий реальный организационный смысл и не зависело от расположения станций внутри здания.

А вообще, разве важно, кто подключен к какой ЛВС? Ведь все равно почти во всех организациях сети объединены между собой. На самом же деле, это действительно зачастую бывает важно. Сетевые администраторы по целому ряду причин любят группировать пользователей ЛВС в соответствии со структурой организации, а не по принципу физического расположения компьютеров. Одной из таких причин является безопасность. Одна ЛВС может содержать веб-серверы и другие компьютеры для общественного пользования. Другая может содержать записи отдела кадров, которые не должны выходить за пределы организации. В этой ситуации наилучшим выходом является объединение компьютеров всех работников отдела в одну ЛВС и запрет на передачу каких-либо данных наружу. Руководство обычно не устраивает заявление о том, что такое решение невозможно реализовать.

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

Еще одна причина — широковещание. Мосты поддерживают широковещание, когда местонахождение адресата неизвестно, и протоколы верхних уровней поддерживают широковещание. Например, если пользователь хочет отправить пакет на IP-адрес х, как ему узнать, какой MAC-адрес подставлять в кадры? Мы изучим этот вопрос более подробно в главе 5, а сейчас в двух словах обрисуем решение проблемы: данная станция должна широковещательным методом послать запрос: «Кто знает, какой MAC-адрес работает с IP-адресом х?» Затем она дожидается ответа. Поскольку количество компьютеров в ЛВС растет, растет и количество широковещательных сообщений. Каждая широковещательная передача потребляет больше ресурсов ЛВС, чем обычный кадр, потому что она направлена каждому компьютеру в ЛВС. Если размеры ЛВС сохраняются не больше чем необходимо, воздействие широковещательного трафика уменьшается.

С широковещанием связана еще одна проблема: время от времени сетевой интерфейс может сломаться или быть неправильно сконфигурирован, и начать генерировать бесконечный поток кадров, получаемый всеми станциями. Если сеть будет действительно неудачна, то некоторые из этих кадров вызовут ответы, которые приведут к еще большему количеству трафика. Это широковещательный шторм (broadcast storm), который состоит в том, что, во-первых, вся пропускная способность сети занята этими бессмысленными кадрами, и, во-вторых, все машины объединенных сетей вынуждены заниматься исключительно обработкой и отвержением этого мусора.

На первый взгляд кажется, что широковещательные штормы можно ограничить путем установки своего рода дамб — разделяя сети мостами или коммутаторами на несколько частей. Однако если речь идет о прозрачности (то есть о предоставлении машинам возможности перенесения в другие ЛВС без каких-либо изменений конфигурации), то широковещательные кадры должны обрабатываться и пересылаться мостами.

Рассмотрев причины того, что компаниям требуются многочисленные локальные сети с ограниченными размерами, давайте вернемся к проблеме разделения логической и физической топологии. Создание физической топологии, чтобы отразить организационную структуру, может добавить работу и стоимость проекта, даже с централизованной проводкой и коммутаторами. Например, если два человека из одного отдела работают в различных зданиях, может быть легче присоединить их к различным коммутаторам, которые являются частью различных ЛВС. Даже если дело обстоит не так, пользователь мог перейти в пределах компании из одного отдела в другой, но остаться в том же офисе, или наоборот — сменить офис, не меняя отдел. Это могло бы привести к тому, что пользователь окажется в неправильной ЛВС, пока администратор не изменяет разъем пользователя от одного коммутатора на другой.

Кроме того, количество компьютеров, принадлежащих различным отделам, возможно, не очень хорошо соответствует количеству портов на коммутаторах; некоторые отделы могут быть слишком малы, а другие настолько крупные, что требуют нескольких коммутаторов. Это приводит к потраченным впустую портам коммутаторов, которые не используются.

Во многих компаниях организационные перестановки происходят постоянно, то есть сетевой администратор постоянно занимается манипуляциями с соединителями и разъемами. А в некоторых случаях такие перестановки оказываются невозможными из-за того, что провод пользовательского компьютера проходит слишком далеко и просто не дотягивается до нужного коммутатора (вследствие непродуманной прокладки кабелей) или доступные порты коммутатора относятся к другой ЛВС.

Пользователи стали требовать у производителей создания более гибких сетей, и те ответили им созданием виртуальных ЛВС (ВЛВС VLAN, Virtual LAN), для внедрения которых необходимо было изменить только программное обеспечение. Виртуальные сети даже были в какой-то момент стандартизованы комитетом IEEE 802. Сейчас они широко применяются. Ниже мы вкратце обсудим виртуальные сети. Дополнительную информацию можно найти в работе (Seifert и Edwards, 2008).

Виртуальные сети построены на основе ВЛВС-совместимых коммутаторов. Для создания системы, построенной на виртуальных ЛВС, сетевому администратору прежде всего нужно решить, сколько всего будет виртуальных сетей, какие компьютеры будут в них входить и как они будут называться. Зачастую ВЛВС (неформально) называют в соответствии с цветами, поскольку тогда сразу становятся понятнее и нагляднее цветные диаграммы, показывающие принадлежность пользователей виртуальным сетям. Скажем, пользователи «красной» сети будут изображены красным цветом, «синей» — синим и т. д. Таким образом, на одном рисунке можно отобразить физическую и логическую структуру одновременно.

В качестве примера рассмотрим ЛВС с мостом, изображенные на рис. 4.44. Здесь девять машин входят в виртуальную сеть С («Серая»), а еще пять машин — в виртуальную сеть Б («Белая»). Машины «серой» сети распределены между двумя коммутаторами, в том числе две машины, подключенные к коммутатору через концентратор.

Рис. 4.44. Две виртуальные сети, серая и белая, в сети с мостом

Чтобы виртуальные сети функционировали корректно, необходимо наличие конфигурационных таблиц в мостах. Эти таблицы сообщают о том, через какие порты производится доступ к тем или иным виртуальным сетям. Когда кадр прибывает, например, из «серой» ВЛВС, его нужно разослать на все порты, помеченные буквой С. Это правило справедливо как для ординарных (то есть однонаправленных) передач, для которых мост не изучает местоположение назначения, так и для групповых и широковещательных. Имейте в виду, что порт может быть помечен сразу несколькими цветами ВЛВС.

В качестве примера предположим, что одна из «серых» станций, подключенных к мосту В1, посылает кадр, на заранее не видимое место назначения. Мост B1 примет кадр и заметит, что он пришел с машины с пометкой С. Поэтому его необходимо залить на все порты (кроме того, с которого пришел кадр), принадлежащие «серой» виртуальной сети. Кадр будет направлен на остальные пять «серых» станций, подключенных к B1, а также по соединению B1 c мостом B2. Мост B2 аналогично перешлет кадр на все порты, помеченные С. При этом кадр будет отослан одной оставшейся станции и концентратору (который передаст кадр всем своим станциям). Концентратор имеет обе метки (С и Б), поскольку к нему подключены станции из обоих ВЛВС. Кадр не посылается через другие порты, кроме имеющих метку С, поскольку мост знает, что станции из «серой» ВЛВС через них недостижимы.

В нашем примере кадр будет передан только от моста В1 к мосту В2, так как машины «серой» ЛВС присоединены к В2. Глядя на «белую» ЛВС мы видим, что порт В2, который соединен с мостом В1, не помечен Б. Это означает, что кадр «белой» ЛВС не будет переслан от В2 к В1. Такое поведение корректно, поскольку к В1 не присоединено ни одной «белой» станции.

Стандарт IEEE 802.1Q

Чтобы реализовать эту схему, мосты должны каким-то образом узнавать, к какой ВЛВС принадлежит входящий кадр. Без этой информации, например, когда мост В2 получает кадр от моста В1 (см. рис. 4.44), он не знает, передавать его «белой» или «серой» ВЛВС. Если мы проектируем новый тип сети, вполне можно было бы просто добавить специальное поле заголовка. Но что делать с Ethernet — доминирующей сетью, у которой нет никаких «запасных» полей, которые можно было бы отдать под идентификатор виртуальной сети?

Комитет IEEE 802 озаботился этим вопросом в 1995 году. После долгих дискуссий было сделано невозможное — изменен формат заголовка кадра Ethernet! Новый формат было опубликован под именем 802.1Q в 1998 году. В заголовок кадра был вставлен флаг ВЛВС, который мы сейчас вкратце рассмотрим. Понятно, что внесение изменений в нечто уже устоявшееся, такое как Ethernet, должно быть произведено каким-то нетривиальным образом. Встают, например, следующие вопросы:

1.    И что, теперь надо будет выбросить на помойку несколько миллионов уже существующих сетевых карт Ethernet?

2.    Если нет, то кто будет заниматься генерированием новых полей кадров?

3.    Что произойдет с кадрами, которые уже имеют максимальный размер?

Конечно, комитет 802 тоже был озабочен этими вопросами, и решение, несмотря

ни на что, было найдено.

Идея состоит в том, что на самом деле поля ВЛВС реально используются только мостами да коммутаторами, а не машинами пользователей. Так, скажем, сеть, изображенную на рис. 4.44, не очень-то волнует их наличие в каналах, идущих от оконечных станций, до тех пор пока кадры не доходят до мостов. Кроме того, чтобы использовать ВЛВС, мосты должны быть ВЛВС-совместимыми. Этот факт делает проект выполнимым.

Что касается старых сетевых карт Ethernet, то выкидывать их не приходится. Комитет 802.3 никак не мог заставить людей изменить поле Тип на поле Длина. Вы можете себе представить, какова была бы реакция на заявление о том, что все существующие карты Ethernet можно выбросить? Тем не менее новые модели 802.Щ-совместимы и могут корректно заполнять поля идентификации виртуальных сетей.

Так как некоторые компьютеры (и коммутаторы) могут быть не совместимы с ВЛВС, то первый встретившийся на пути кадра ВЛВС-совместимый мост вставляет это поле, а последний — вырезает его. Пример смешанной топологии показан на рис. 4.45. В этом примере ВЛВС-совместимые компьютеры генерируют снабженные тегами (то есть 802.1Q) кадры непосредственно, и дальнейшие коммутаторы используют эти теги. Закрашенные значки — ВЛВС-совместимые, пустые — нет.

В соответствии с 802.1Q, кадры «окрашиваются» в зависимости от порта, на котором они получены. Для применения этого метода все машины одного порта должны принадлежать одной ВЛВС, что уменьшает гибкость. Например, на рис. 4.44 это свойство выполнено для всех портов, где отдельный компьютер соединяется с мостом, но не для порта, где концентратор соединяется с мостом B2.

Дополнительно, мост может использовать протокол более высокого уровня, чтобы выбрать цвет. Таким образом, кадры, прибывающие в порт, могли бы быть помещены в различные ВЛВС в зависимости от того, переносят ли они IP-пакеты или кадры PPP.

Рис. 4.45. ЛВС с мостами, частично совместимая с ВЛВС. Затененные символы — это ВЛВС-совместимые устройства. Все остальные не совместимы с виртуальными сетями

Возможны и другие методы, но они не поддерживаются в 802.1Q. Например, для выбора цвета ВЛВС может использоваться MAC-адрес. Это могло бы быть полезно для кадров из соседних 802.11 ЛВС, в которых ноутбуки посылают кадры через различные порты, в зависимости от своего перемещения. Один MAC-адрес был бы тогда отображен на одну и ту же ВЛВС, независимо от порта, через который он входит в сеть.

Что касается проблемы кадров, длина которых превышает 1518 байт, то в стандарте 802.1Q она решается путем повышения лимита до 1522 байт. К счастью, только ВЛВС-совместимые компьютеры и коммутаторы обязаны поддерживать такие длинные кадры.

Теперь рассмотрим собственно формат 802.1Q. Он показан на рис. 4.46. Единственное изменение, которое мы тут видим, — это добавление пары 2-байтовых полей. Первое называется Идентификатором протокола ВЛВС (VLAN protocol ID). Оно всегда имеет значение 0х8100. Поскольку это число превышает 1500, то все сетевые карты Ethernet интерпретируют его как «тип», а не как «длину». Неизвестно, что будет делать с таким кадром карта, несовместимая с 802.1Q, поэтому такие кадры, по идее, не должны к ней никоим образом попадать.

802.3

Рис. 4.46. Форматы кадров Ethemet-стандартов 802.3 и 802.1Q

Во втором двухбайтовом поле есть три вложенных поля. Главным из них является Идентификатор ВЛВС (VLAN identifier), который занимает 12 младших бит. Он содержит ту информацию, из-за которой все эти преобразования форматов, собственно, и были затеяны: в нем указан «цвет» виртуальной сети, которой принадлежит кадр. Трехбитовое поле Приоритет не имеет вообще ничего общего с виртуальными сетями. Просто изменение формата Ethernet-кадра — это такой ежедекадный ритуал, который занимает три года и исполняется какой-то сотней людей. Почему бы не оставить память о себе в виде трех дополнительных бит, да еще и с таким привлекательным назначением? Поле Приоритет позволяет различать трафик «жесткого» реального времени, трафик «мягкого» реального времени и трафик, для которого время передачи не критично. Это позволяет обеспечить более высокое качество обслуживания в Ethernet. Оно используется также при передаче голоса по Ethernet (хотя вот уже четверть века в IP имеется подобное поле и никто никогда его не использовал).

Последнее поле, CFI (Canonical Format Indicator — индикатор классического формата), следовало бы назвать Индикатором эгоизма компании (CEI — Corporate ego indicator). Изначально оно предназначалось для того, чтобы показывать порядок бит в MAC-адресе («остроконечники против тупоконечников»), однако в пылу дискуссий об этом как-то забыли. Его присутствие сейчас означает, что поле данных содержит усохший кадр 802.5, который ищет еще одну сеть формата 802.5 и в Ethernet попал совершенно случайно. То есть, на самом деле, он просто использует Ethernet в качестве средства передвижения. Все это, конечно, практически никак не связано с обсуждаемыми в данном разделе виртуальными сетями. Но политика комитета стандартизации не сильно отличается от обычной политики: если ты проголосуешь за введение в формат моего бита, то я проголосую за твой бит.

Как уже упоминалось выше, когда кадр с флагом виртуальной сети приходит на ВЛВС-совместимый коммутатор, последний использует идентификатор виртуальной сети в качестве индекса таблицы, в которой он ищет, на какие порты послать кадр. Но откуда берется эта таблица? Если она разрабатывается вручную, это означает возврат в исходную точку: ручное конфигурирование коммутаторов. Вся прелесть прозрачности мостов состоит в том, что они настраиваются автоматически и не требуют для этого никакого вмешательства извне. Было бы очень стыдно потерять это свойство. К счастью, мосты для виртуальных сетей также являются самонастраивающимися. Настройка производится на основе информации, содержащейся во флагах приходящих кадров. Если кадр, помеченный как ВЛВС 4, приходит на порт 3, значит, несомненно, одна из машин, подключенных к этому порту, находится в виртуальной сети 4. Стандарт 802.1Q вполне четко поясняет, как строятся динамические таблицы. При этом делаются ссылки на соответствующие части стандарта 802.1D.

Прежде чем завершить разговор о маршрутизации в виртуальных сетях, необходимо сделать еще одно замечание. Многие пользователи сетей Интернет и Ethernet фанатично привязаны к сетям без установления соединения и неистово противопоставляют их любым системам, в которых есть хотя бы намек на соединение на сетевом или канальном уровне. Однако в виртуальных сетях один технический момент как раз-таки очень сильно напоминает установку соединения. Речь идет о том, что работа виртуальной сети невозможна без того, чтобы в каждом кадре был идентификатор, использующийся в качестве индекса таблицы, встроенной в коммутатор. По этой таблице определяется дальнейший вполне определенный маршрут кадра. Именно это и происходит в сетях, ориентированных на соединение. В системах без установления соединения маршрут определяется по адресу назначения, и там отсутствуют какие-либо идентификаторы конкретных линий, через которые должен пройти кадр. Более подробно мы рассмотрим эту тенденцию в главе 5.

4.9. Резюме

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

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

Было разработано несколько алгоритмов динамического распределения каналов. Протокол ALOHA (чистый или дискретный) используется в многочисленных вариантах в реальных системах, например в кабельных модемах и RFID. Его усовершенствование — возможность прослушивать состояние канала, тогда станции могут отказываться от передачи, когда слышат, что канал занят другой станцией. Применение этого метода — контроля несущей — повлекло создание различных CSMA протоколов, применяемых в локальных и региональных сетях. Это основа классических сетей Ethernet и сетей 802.11.

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

Дополнительной проблемой беспроводных ЛВС является трудность обнаружения коллизий передач и возможность различий зон обслуживания станций. В доминирующей беспроводной ЛВС, IEEE 802.11, станции, чтобы смягчить первую проблему, используют CSMA/CA, оставляя маленькие промежутки, чтобы избежать коллизий. Станции могут также использовать протокол RTS/CTS, чтобы сражаться со скрытыми терминалами, которые возникают из-за второй проблемы. IEEE 802.11 обычно используется, чтобы соединить ноутбуки и другие устройства с точками доступа, но он может использоваться и между устройствами. Может использоваться любой из нескольких физических уровней, в том числе многоканальный FDM с и без нескольких антенн, и расширение спектра.

Как и 802.11, считыватели и метки RFID используют протокол произвольного доступа, чтобы сообщить идентификаторы. Другие беспроводные персональные и городские сети имеют отличающееся устройство. Система Bluetooth осуществляет беспроводное присоединение к компьютеру наушников и других видов периферийных устройств. IEEE 802.16 обеспечивает широкую область беспроводного доступа к Интернету для неподвижных и мобильных компьютеров. Обе эти сети используют централизованную схему на основе соединений, где ведущее устройство Bluetooth и базовая станция WiMAX решают, когда каждая станция может послать или получить данные. Для 802.16 эта схема поддерживает различное качество обслуживания для трафика в реальном времени, такого как телефонные звонки, и интерактивного трафика, такого как просмотр веб-страниц. Сложность ведущего устройства Bluetooth приводит к дешевизне ведомых устройств.

Ethernet является доминирующей технологией проводных локальных вычислительных сетей. Классический Ethernet производит распределение канала при помощи метода CSMA/CD с желтым кабелем толщиной с садовый шланг, который тянулся от машины к машине. Архитектура изменилась, скорости возросли от 10 Мбит/с до 1 Гбит/с и продолжают расти. Теперь линии точка-точка, такие как витая пара, присоединяются к концентраторам и коммутаторам. С современными коммутаторами и полнодуплексными каналами нет никакой конкуренции в каналах, и коммутарор может пересылать кадры между различными портами параллельно.

Когда в здании много локальных сетей, необходим какой-то способ их объединения. Для этих целей используются plug-and-play устройства — мосты. При построении мостов применяются алгоритм обратного обучения и алгоритм связующего дерева.

С добавлением в современные коммутаторы этих функций термины «мост» и «коммутатор» стали взаимозаменяемы.

Для упрощения управления ЛВС с мостами появились виртуальные локальные сети, которые позволили отделить физическую топологию от логической. Был разработан стандарт для виртуальных локальных сетей — IEEE 802.1Q, вводящий новый формат Ethernet кадров.

Вопросы

1.    Для решения задачи используйте формулу, приведенную в данной главе, записав ее в общем виде. Кадры для передачи прибывают случайным образом на 100-Мбит/с канал. Если в момент прибытия канал оказывается занят, кадр ставится в очередь ожидания. Длина кадра распределяется по экспоненциальному закону с математическим ожиданием, равным 10 000 бит/ кадр. Для каждой из приведенных ниже скоростей прибытия кадров вычислите задержку (включая время ожидания в очереди и время передачи) кадра средней длины.

1)    90 кадров/с.

2)    900 кадров/с.

3)    9000 кадров/с.

2.    Группа из N станций совместно использует канал чистой системы ALOHA, работающий со скоростью 56 Кбит/с. Каждая станция передает 1000-битный кадр в среднем каждые 100 с, даже если предыдущий кадр еще не был передан (например, станции могут буферизировать исходящие кадры). Каково максимальное значение N?

3.    Сравните время задержки чистой и дискретной систем ALOHA при низкой нагрузке. У какой из систем это время будет меньшим? Поясните свой ответ.

4.    Большая группа пользователей системы ALOHA формирует 50 запросов в секунду, включая первичные и повторные передачи. Время разделено на интервалы по 40 мс.

1)    Каковы шансы успеха с первой попытки?

2)    Какова вероятность того, что перед успехом произойдет ровно k столкновений?

3)    Чему равно среднее число попыток передачи?

5.    В дискретной системе ALOHA с бесконечным числом пользователей средний период ожидания станции между столкновением и повторной попыткой составляет 4 временных интервала. Нарисуйте зависимость задержки от потока в канале для данной системы.

6.    Какова длина слота разрешения спора в CSMA/CD для:

1)    2-километрового двухпроводного кабеля (скорость распространения сигнала составляет 82 % скорости распространения сигнала в вакууме)?

2)    40-километрового многомодового оптоволоконного кабеля (скорость распространения сигнала составляет 65 % скорости распространения сигнала в вакууме)?

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

8.    В протоколе двоичного отсчета объясните, как станция с более низким номером может лишаться возможности отправки пакета

9.    Шестнадцать станций, пронумерованных от 1 до 16, соревнуются за право использования общего канала, используя протокол движения по адаптивному дереву. Сколько интервалов времени потребуется для разрешения спора, если все станции, чьи номера являются простыми числами, одновременно станут готовыми к передаче?

10.    Рассмотрим пять беспроводных станций, A, B, C, D и E. Станция А может общаться со всеми остальными станциями. B может общаться с A, C и E. C может общаться с A, B и D. D может общаться с A, C и E. E может общаться с A, D и B.

1)    Когда A посылает в B, какие другие коммуникации возможны?

2)    Когда B посылает в A, какие другие коммуникации возможны?

3)    Когда B посылает в C, какие другие коммуникации возможны?

11.    Шесть станций, отмеченных буквами A—F, взаимодействуют друг с другом по протоколу MACA. Возможна ли ситуация двух одновременных передач данных? Ответ поясните.

12.    В семиэтажном офисном здании на каждом этаже расположено по 15 офисов. В каждом офисе на стене установлен разъем для подключения терминала, так что в вертикальной плоскости эти разъемы образуют прямоугольную сетку с расстоянием по 4 м между гнездами, как по горизонтали, так и по вертикали. Предполагая, что можно проложить кабель по прямой между любой парой гнезд, по горизонтали, вертикали или диагонали, сосчитайте, сколько метров кабеля потребуется для соединения всех гнезд при помощи:

1)    конфигурации «звезда» с одним маршрутизатором посередине;

2)    классической сети 802.3.

13.    Чему равна скорость в бодах стандартной локальной сети Ethernet со скоростью 10 Мбит/с?

14.    Как будет выглядеть манчестерский код для классической сети Ethernet следующей двоичной последовательности: 0001110101?

15.    В сети с протоколом CSMA/CD (не 802.3) длиной 1 км со скоростью передачи данных 10 Мбит/с скорость распространения сигнала составляет 200 м/мкс. Повторителей в этой системе нет. Длина кадров данных равна 256 бит, включая 32 бита заголовка, контрольную сумму и другие накладные расходы. Первый интервал времени после успешной передачи кадра резервируется для передачи получателем 32-битового кадра с подтверждением. Какова эффективная скорость передачи данных без учета накладных расходов при предположении о том, что столкновений нет?

16.    Две станции в сети с протоколом CSMA/CD пытаются передавать длинные (состоящие из нескольких кадров) файлы. После передачи каждого кадра они состязаются за канал при помощи алгоритма двоичной экспоненциальной выдержки. Какова вероятность того, что борьба закончится в k-м раунде, и чему равно среднее число раундов в периоде состязания?

17.    IP-пакет необходимо передать по сети Ethernet. Длина пакета — 60 байт, включая все служебные поля. Если не используется LLC, необходимо ли заполнение Ethernet-кадра? Если да, то сколькими байтами?

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

19.    В некоторых изданиях можно прочесть, что максимальный размер кадра Ethernet равен 1522 байтам (а не 1500 байтам). Ошибаются ли авторы этих изданий? Ответ поясните.

20.    Сколько кадров в секунду может обрабатывать Gigabit Ethernet? Хорошо подумайте перед тем, как отвечать. Подсказка: имеет значение тот факт, что это именно Gigabit Ethernet.

21.    Назовите две сетевые технологии, позволяющие паковать кадры друг за другом. Чем выгодно такое свойство?

22.    На рис. 4.24 показаны четыре станции: A, B, C и D. Как вы думаете, какая из двух последних станций находится ближе к A и почему вы так решили?

23.    Приведите пример, показывающий, что в протоколе 802.11 RTS/CTS немного отличается от RTS/CTS в протоколе MACA.

24.    В беспроводной ЛВС с одной точкой доступа есть 10 клиентских станций. У четырех станций скорость передачи данных составляет 6 Мбит/с, у других четырех — 18 Мбит/с и у еще двух — 54 Мбит/с. Какова скорость передачи данных каждой станции, когда все десять станций посылают данные одновременно и

1)    TXOP не используется?

2)    TXOP используется?

25.    Пусть по 11 Мбит/c локальной сети 802.11b передаются друг за другом по радиоканалу 64-байтные кадры с вероятностью ошибки 10-7 на бит. Сколько кадров в секунду в среднем будет искажаться при передаче?

26.    Сеть стандарта 802.16 обладает каналом с шириной полосы пропускания 20 МГц. Сколько бит в секунду может отправлять по ней абонентская станция?

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

28.    Назовите два сходства и два отличия WiMAX от 802.11.

29.    На рис. 4.31 видно, что устройство системы Bluetooth может находиться одновременно в двух пикосетях. Почему одно и то же устройство не может являться главным сразу в двух пикосетях?

30.    Каков максимальный размер поля данных для кадра Bluetooth с тремя слотами на базовой скорости? Объясните свой ответ.

31.    На рис. 4.21 показано несколько протоколов физического уровня. Какой из них больше всего напоминает протокол физического уровня Bluetooth? В чем состоит основная разница этих двух протоколов?

32.    Как упомянуто в разделе 4.6.6, эффективность кадра с одним слотом с кодированием повторения составляет приблизительно 13 % на базовой скорости данных. Какова будет эффективность, если вместо этого будет использоваться 5-слотовый кадр?

33.    Кадры-«маяки» в варианте 802.11 с методом частотных скачков содержат время пребывания. Как вы думаете, аналогичные кадры-«маяки» в Bluetooth также содержат время пребывания? Обсудите свой ответ.

34.    Предположим, что вокруг RFID-считывателя есть 10 меток. Каково лучшее значение Q? Насколько вероятно, что одна метка отвечает в данном слоте без коллизий?

35.    Перечислите некоторые из проблем безопасности системы RFID.

36.    Коммутатор, предназначенный для работы с Fast Ethernet, имеет объединительную плату, которая может передавать данные со скоростью 10 Гбит/с. Сколько кадров в секунду может быть обработано таким коммутатором?

37.    Опишите вкратце разницу между коммутаторами с ожиданием (store-and-forward) и сквозными (cut-through) коммутаторами.

38.    Рассмотрите расширенную ЛВС, содержащую мосты B1 и B2, на рис. 4.38, б. Предположите, что хэш-таблицы в двух мостах пусты. Перечислите все порты, в которые будет отправлен пакет для следующей последовательности передач данных:

1)    А посылает пакет C.

2)    E посылает пакет F.

3)    F посылает пакет E.

4)    Г посылает пакет E.

5)    D посылает пакет A.

6)    B посылает пакет F.

39.    Коммутаторы с ожиданием имеют преимущество перед сквозными коммутаторами при обработке испорченных кадров. Объясните, почему

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

41.    Чтобы виртуальная сеть заработала, мостам и коммутаторам нужны конфигурационные таблицы. А что если в виртуальных сетях, показанных на рис. 4.44, использовать концентраторы вместо коммутаторов? Понадобятся ли им конфигурационные таблицы? Ответ поясните.

42.    На рис. 4.45 коммутатор обычного оконечного домена (справа) является ВЛВС-совмес-тимым. Можно было бы поставить здесь обычный коммутатор? Ответ поясните.

43.    Напишите программу, симулирующую поведение протокола CSMA/CD в системе Ethernet с N станциями, готовыми к передаче во время передачи по каналу кадра. Программа должна выводить временные метки тех моментов, когда каждая из станций смогла успешно начать передачу своего кадра. Пусть часы изменяют свое состояние каждый такт (51,2 мкс), и обнаружение коллизии с отправкой преднамеренной помехи, сообщающей об этом, также занимает один такт. Все кадры имеют максимально допустимую длину.

Глава 5

Сетевой уровень

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

Для достижения этих целей сетевой уровень должен обладать информацией о топологии сети (то есть о множестве всех маршрутизаторов и связей) и выбирать нужный путь по этой сети, даже если она достаточно крупная. При выборе маршрутизаторов он должен также заботиться о том, чтобы нагрузка на маршрутизаторы и линии связи была, по возможности, более равномерной. Наконец, если источник и приемник находятся в различных сетях, именно сетевой уровень должен уметь решать проблемы, связанные с различиями в сетях. В данной главе мы рассмотрим все эти аспекты и проиллюстрируем их в основном на примере Интернета и его протокола сетевого уровня — IP.

5.1.    Вопросы проектирования сетевого уровня

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

5.1.1.    Метод коммутации пакетов с ожиданием

Прежде чем начать подробное рассмотрение сетевого уровня, необходимо восстановить в памяти окружение, в котором ему приходится функционировать. Оно показано на рис. 5.1. Основными компонентами сети являются устройства интернет-провайдера (маршрутизаторы, соединенные линиями связи), показанные внутри затененного овала, а также устройства, принадлежащие клиенту и показанные вне овала. Хост H1 напрямую соединен с одним из маршрутизаторов интернет-провайдера А

(как, например, домашний компьютер, подключенный к DSL-модему). Хост H2, напротив, находится в ЛВС (например, офисной сети Ethernet) с маршрутизатором F, принадлежащим клиенту, который с ним работает. Этот маршрутизатор связывается с интернет-провайдером по выделенной линии. Мы показали F вне овала, потому что он не принадлежит интернет-провайдеру. Однако в контексте данной главы мы будем считать маршрутизаторы клиента частью сети интернет-провайдера, поскольку в них применяются те же самые алгоритмы, что и в маршрутизаторах интернет-провайдеров (а основным предметом рассмотрения будут именно алгоритмы).

Рис. 5.1. Окружение, в котором функционируют протоколы сетевого уровня

Система работает следующим образом. Хост, у которого есть пакет для передачи, посылает его на ближайший маршрутизатор либо в своей ЛВС, либо по двухточечному соединению интернет-провайдеру. Там пакет хранится до тех пор, пока не будет принят целиком и не пройдет полную обработку, включая верификацию контрольной суммы. Затем он передается по цепочке маршрутизаторов, которая в итоге приводит к пункту назначения. Такой механизм называется коммутацией пакетов с ожиданием (store-and-forward), и мы уже рассматривали его в предыдущих главах.

5.1.2. Сервисы, предоставляемые транспортному уровню

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

♦    Сервисы сетевого уровня не должны зависеть от технологии маршрутизатора.

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

♦    Сетевые адреса, доступные транспортному уровню, должны использовать единую систему нумерации, даже между локальными и глобальными сетями..

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

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

Из этого следует, что сетевой сервис должен быть сервисом, не требующим установки соединения и состоящим в основном из примитивов SEND PACKET (послать пакет) и RECEIVE PACKET (принять пакет). В частности, сюда нельзя включать упорядочивание пакетов и контроль потока — все равно эти действия будет выполнять хост. От того что одна и та же работа будет выполнена дважды, качество обслуживания не повысится. Такое рассуждение — пример применения «сквозного» принципа (end-to-end argument), оказавшего значительное влияние на формирование Интернета (Saltzer и др., 1984). Кроме того, каждый пакет должен содержать полный адрес получателя, так как пересылка производится независимо от предшествующих пакетов.

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

Этот спор остается актуальным даже по прошествии нескольких десятков лет. Раньше самые распространенные сети передачи данных (такие как X.25, использовавшаяся в 70-х, и популярная в 80-х Frame Relay) были ориентированы на соединение. Однако после появления ARPANET и на ранних этапах развития Интернета сетевые уровни без установления соединения стали чрезвычайно популярными. Сейчас протокол IP является вездесущим символом успеха. На его популярность не повлияло даже появление ориентированной на соединение технологии ATM, созданной в 80-х годах с целью заменить IP: в настоящее время ATM используется только в отдельных случаях, тогда как в ведении IP оказываются все телефонные сети. Однако с ростом требований к качеству обслуживания развитие Интернета предполагает появление новых возможностей, ориентированных на соединение. В качестве примеров таких технологий можно привести MPLS (MultiProtocol Label Switching, «мультипротокольная коммутация по меткам»), о которой мы поговорим в этой главе, и VLAN, которую мы рассматривали в главе 4. Обе эти технологии сейчас широко используются.

5.1.3. Реализация сервиса без установления соединения

Рассмотрев два класса сервисов, которые сетевой уровень может предоставлять своим пользователям, можно перейти к обсуждению устройства этого уровня. Возможны два варианта в зависимости от типа сервиса. Если предоставляется сервис без установления соединения, пакеты внедряются в сеть по отдельности, и их маршруты рассчитываются независимо. При этом никакой предварительной настройки не требуется. В этом случае пакеты часто называют дейтаграммами (datagrams), по аналогии с телеграммами, а сети соответственно дейтаграммными (datagram network). При использовании сервиса, ориентированного на соединение, весь путь от маршрутизатора-отправителя до маршрутизатора-получателя должен быть установлен до начала передачи каких-либо пакетов данных. Такое соединение называется виртуальным каналом (VC, Virtual Circuit), по аналогии с физическими каналами, устанавливаемыми в телефонной системе. Сеть при этом называется сетью виртуального канала (virtual-circuit network). В этом разделе мы обсудим дейтаграммные сети; в следующем разделе — сети виртуального канала.

Рассмотрим принцип работы дейтаграммных сетей. Пусть процесс P1 (рис. 5.2) хочет послать длинное сообщение для Р2. Он передает свое послание транспортному уровню, сообщает ему о том, что доставить данные необходимо процессу Р2, выполняющемуся на хосте Н2. Код транспортного уровня исполняется на хосте Н1; более того, обычно он является частью операционной системы. Заголовок транспортного уровня вставляется в начало сообщения, и в таком виде оно передается на сетевой уровень. Обычно это просто еще одна процедура операционной системы.

Предположим, что в нашем примере сообщение в четыре раза длиннее максимального размера пакета, поэтому сетевой уровень должен разбить его на четыре пакета (1, 2, 3 и 4) и послать их все поочередно на маршрутизатор А с использованием какого-нибудь протокола двухточечного соединения, например PPP. Здесь вступает в игру интернет-провайдер. Каждый маршрутизатор имеет свою внутреннюю таблицу, по которой он определяет дальнейший путь пакета при каждом из возможных адресов назначения. Каждая запись таблицы состоит из двух полей: пункт назначения (адресат) и выходящая линия для данного адресата. Во втором поле могут использоваться только линии, непосредственно соединенные с данным маршрутизатором. Так, например, на рис. 5.2 у маршрутизатора А имеются только две исходящие линии — ведущие к В и к С, — поэтому все входящие пакеты должны пересылаться на какой-то из этих двух маршрутизаторов, даже если они не являются адресатами. Изначальная таблица маршрутизации А показана на рисунке под соответствующей надписью.

В маршрутизаторе A пакеты 1, 2 и 3, поступившие на вход, кратковременно сохраняются для верификации контрольной суммы. Затем в соответствии с таблицей А каждый пакет пересылается по исходящему соединению на маршрутизатор С с использованием нового кадра. После этого пакет 1 уходит на Е, откуда доставляется на маршрутизатор локальной сети, F. Когда он прибывает на F, он передается внутри кадра по ЛВС на хост Н2. Пакеты 2 и 3 следуют по тому же маршруту.

Рис. 5.2. Маршрутизация внутри дейтаграммной подсети

Однако с пакетом 4 связана несколько иная история. После прибытия на А он пересылается на маршрутизатор В, несмотря на то что адресом назначения является F, как и у первых трех пакетов. По каким-то своим причинам маршрутизатор А решил послать пакет 4 по новому маршруту. Может быть, это стало следствием затора где-то на линии ACE, возникшего при пересылке трех пакетов, в результате чего маршрутизатор решил обновить свою таблицу (на рисунке показана под надписью «В конце»). Алгоритм, управляющий таблицами маршрутизации и принимающий решения, называется алгоритмом маршрутизации (routing algorithm). Именно изучению алгоритмов маршрутизации будет уделено основное внимание в этой главе. Как мы увидим, существует несколько типов таких алгоритмов.

IP (Internet Protocol, «межсетевой протокол»), составляющий основу всей сети Интернет, является наиболее ярким примером сетевого сервиса без установления соединения. Каждый пакет содержит IP-адрес назначения, с помощью которого маршрутизатор осуществляет индивидуальную отправку пакета. В пакетах IPv4 используются адреса длиной 32 бита, а в IPv6 — 128 бит. Более подробно о протоколах IP мы поговорим далее в этой главе.

5.1.4. Реализация сервиса с установлением соединения

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

В качестве примера рассмотрим ситуацию, изображенную на рис. 5.3. Хост Н1 установил соединение с хостом Н2. Это соединение запоминается и становится первой записью во всех таблицах маршрутизации. Так, первая строчка таблицы маршрутизатора А говорит о том, что если пакет с идентификатором соединения 1 пришел с хоста Н1, то его нужно направить на С с идентификатором соединения 1. Точно так же первая запись С направляет пакет на Е все с тем же идентификатором соединения 1.

Рис. 5.3. Маршрутизация в сети виртуального канала

Теперь рассмотрим, что будет, если хост Н3 захочет установить соединение с Н2. Он выбирает идентификатор соединения 1 (у него просто нет выбора, поскольку это на данный момент единственное существующее соединение) и просит сеть установить виртуальный канал. Таким образом, в таблице появляется вторая запись. Обратите внимание на то, что здесь возникает, на самом деле, конфликт, потому что если А еще может отличить пакеты соединения 1, пришедшие с Н1, от пакетов соединения 1, пришедших с Н3, то С такой возможности не имеет. По этой причине А присваивает новый идентификатор соединения исходящему трафику и тем самым создает второе соединение. Предотвращение конфликтов подобного рода является причиной того, почему маршрутизаторам нужна возможность изменения идентификаторов соединения в исходящих пакетах. Иногда этот процесс называется коммутацией меток (label switching). Одним из примеров сетевого сервиса, ориентированного на соединение, является MPLS (MultiProtocol Label Switching, «мультипротокольная коммутация по меткам»). Он используется в сетях интернет-провайдеров; при этом IP-пакеты получают MPLS-заголовок, содержащий 20-битный идентификатор соединения или метку. Если интернет-провайдер устанавливает длительное соединение для передачи крупных объемов данных, MPLS часто остается невидимым для клиентов. Однако сейчас он становится все более необходимым в случаях, когда на первый план выходит качество предоставляемого сервиса, а также для решения других задач, связанных с обменом данными. К обсуждению MPLS мы еще вернемся далее в этой главе.

5.1.5. Сравнение сетей виртуальных каналов и дейтаграммных сетей

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

Таблица 5.1. Сравнение виртуальных каналов и дейтаграмм

Проблема

Дейтаграммы

Виртуальные каналы

Установка канала

Не требуется

Требуется

Адресация

Каждый пакет содержит полный адрес отправителя и получателя

Каждый пакет содержит короткий номер виртуального канала

Информация о состоянии

Маршрутизаторы не содержат информации о состоянии

Каждый виртуальный канал требует места в таблице маршрутизатора

Маршрутизация

Маршрут каждого пакета выбирается независимо

Маршрут выбирается при установке виртуального канала. Каждый пакет следует по этому маршруту

Эффект от выхода из строя маршрутизатора

Никакого, кроме потерянных пакетов

Все виртуальные каналы, проходившие через отказавший маршрутизатор, прекращают существование

Обеспечение качества обслуживания

Трудно реализовать

Легко реализуется при наличии достаточного количества ресурсов для каждого виртуального канала

Борьба с перегрузкой

Трудно реализовать

Легко реализуется при наличии достаточного количества ресурсов для каждого виртуального канала

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

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

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

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

В системах обработки транзакций (например, при запросе магазина на верификацию кредитной карты) накладные расходы на установку соединения и удаление виртуального канала могут сильно снизить потребительские свойства сети. Если объем информации, передаваемой во время одного соединения, невелик, то использование виртуального канала не имеет смысла. Однако в случае длительных операций, таких как обмен данными через VPN внутри одной компании, постоянные виртуальные каналы (установленные вручную и не разрываемые месяцами и даже годами) могут оказаться полезными.

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

5.2. Алгоритмы маршрутизации

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

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

Полезно понимать разницу между маршрутизацией, при которой системе приходится делать выбор определенного маршрута следования, и пересылкой — действием, происходящим при получении пакета. Можно представить себе маршрутизатор как устройство, в котором функционируют два процесса. Один из них обрабатывает приходящие пакеты и выбирает для них по таблице маршрутизации исходящую линию. Такой процесс называется пересылкой (forwarding). Второй процесс отвечает за заполнение и обновление таблиц маршрутизации. Именно здесь в игру вступает алгоритм маршрутизации.

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

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

Такие цели, как справедливость и эффективность, могут показаться очевидными — вряд ли кто-нибудь станет возражать против них, — однако они зачастую оказываются взаимоисключающими. Для примера рассмотрим ситуацию, показанную на рис. 5.4.

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

Рис. 5.4. Конфликт справедливости и оптимальности

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

Алгоритмы выбора маршрута можно разбить на два основных класса: неадаптивные и адаптивные. Неадаптивные алгоритмы не учитывают при выборе маршрута топологию и текущее состояние сети и не измеряют трафик на линиях. Вместо этого выбор маршрута для каждой пары станций производится заранее, в автономном режиме, и список маршрутов загружается в маршрутизаторы во время загрузки сети. Такая процедура иногда называется статической маршрутизацией (static routing). Поскольку статическая маршрутизация не реагирует на сбои, она, как правило, используется в тех случаях, когда выбор маршрута очевиден. Например, маршрутизатор F на рис. 5.3 должен отправлять пакеты, передаваемые по сети, на маршрутизатор E независимо от конечного адреса назначения.

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

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

5.2.1. Принцип оптимальности маршрута

Прежде чем перейти к рассмотрению отдельных алгоритмов, возможно, следует привести некие общие положения, описывающие оптимальные маршруты, вне зависимости от топологии или трафика. Такой основополагающей идеей является принцип оптимальности (Беллман, 1957). В соответствии с этим принципом, если маршрутизатор располагается на оптимальном маршруте от маршрутизатора I к маршрутизатору K, то оптимальный маршрут от маршрутизатора J к маршрутизатору K совпадет с частью первого маршрута. Чтобы убедиться в этом, обозначим часть маршрута от маршрутизатора I к маршрутизатору J как г1, а остальную часть маршрута — r2. Если бы существовал более оптимальный маршрут от маршрутизатора J к маршрутизатору K, чем r2, то его можно было объединить с r1, чтобы улучшить маршрут от маршрутизатора I к маршрутизатору K, что противоречит первоначальному утверждению о том, что маршрут г1г2 является оптимальным.

Прямым следствием принципа оптимальности является возможность рассмотрения множества оптимальных маршрутов от всех источников к конкретным приемникам в виде дерева, имеющего приемник в качестве корня. Такое дерево называется входным деревом (sink tree). Оно изображено на рис. 5.5, б. Расстояния измеряются количеством транзитных участков. Цель всех алгоритмов выбора маршрутов заключается в вычислении и использовании входных деревьев для всех маршрутизаторов.

Рис. 5.5. Сеть (а); входное дерево для маршрутизатора B (б)

Обратите внимание на то, что входное дерево не обязательно является уникальным; у одной сети может существовать несколько деревьев с одинаковыми длинами путей. Если мы будем считать все возможные пути допустимыми, мы получим более общую структуру, и наше дерево будет подходить под определение направленного ациклического графа (directed acyclic graph, DAG). В таких графах нет циклов. Мы будем использовать понятие входного дерева для обозначения обоих вариантов. Оба они также основываются на предположении, что пути не мешают друг другу (из этого следует, в частности, что появление затора на одном пути не приводит к изменению другого пути).

Поскольку входное дерево действительно является деревом, оно не содержит петель, поэтому каждый пакет будет доставлен за конечное и ограниченное число пересылок. На практике все это не так просто. Линии связи и маршрутизаторы могут выходить из строя и снова появляться в сети во время выполнения операции, поэтому у разных маршрутизаторов могут оказаться различные представления о текущей топологии сети. Кроме того, мы обошли вопрос о том, собирает ли маршрутизатор сам информацию для вычисления входного дерева, или эта информация каким-то другим образом поступает к нему. Мы вскоре рассмотрим этот вопрос. Тем не менее принцип оптимальности и входное дерево — это те точки отсчета, относительно которых можно измерять эффективность различных алгоритмов маршрутизации.

5.2.2. Алгоритм нахождения кратчайшего пути

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

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

Концепция кратчайшего пути (shortest path) требует некоторого пояснения. Один из способов измерения длины пути состоит в подсчете количества транзитных участков. В таком случае пути ABC и ABE на рис. 5.6 имеют одинаковую длину. Можно измерять расстояния в километрах. В таком случае окажется, что путь ABC значительно длиннее пути ABE (предполагается, что рисунок изображен с соблюдением масштаба).

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

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

Рис. 5.6. Первые шесть шагов вычисления кратчайшего пути от A к D. Стрелка указывает на рабочий узел

Известно несколько алгоритмов вычисления кратчайшего пути между двумя узлами графа. Один из них был создан знаменитым Дейкстрой (Dijkstra) в 1959 году. Он находит кратчайшие пути между отправителем и всеми возможными адресами назначения в данной сети. Каждый узел помечается (в скобках) расстоянием до него от узла отправителя по наилучшему известному пути. Эти расстояния должны быть неотрицательными; если они основаны на реальных величинах — таких как пропускная способность и время задержки, — это условие будет выполнено. Вначале пути неизвестны, поэтому все узлы помечаются символом бесконечности. По мере работы алгоритма и нахождения путей отметки узлов изменяются, показывая оптимальные пути. Отметка может быть постоянной или экспериментальной. Вначале все отметки являются ориентировочными. Когда выясняется, что отметка действительно соответствует кратчайшему возможному пути, она становится постоянной и в дальнейшем не изменяется.

Чтобы показать, как работает этот алгоритм, рассмотрим взвешенный ненаправленный граф на рис. 5.6, а, где весовые коэффициенты соответствуют, например, расстояниям. Мы хотим найти кратчайший путь от A к D. Для начала мы черным кружком помечаем узел A как постоянный. Затем мы исследуем все соседние с ним узлы, указывая около них расстояние до узла A. Если отыскивается более короткий путь к какому-либо узлу, то вместе с указанием расстояния в отметке меняется и узел, через который прошел более короткий путь. Таким образом, позднее можно восстановить весь путь. Если бы в сети было более одного кратчайшего пути от A до D и мы хотели бы найти их все, нам нужно было бы запоминать все узлы, которые позволяют дойти до данного узла, пройдя одинаковое расстояние.

Рассмотрев все соседние с A узлы, мы помечаем ближайший узел как постоянный, как показано на рис. 5.6, б. Этот узел становится новым рабочим узлом.

Теперь мы повторяем ту же процедуру с узлом B, исследуя все его соседние узлы. Если сумма расстояния от узла B и значения отметки в узле B (расстояния от A до B) оказывается меньше, чем отметка у исследуемого узла (уже найденное другим путем расстояние от A), это значит, что найден более короткий путь, поэтому пометка узла изменяется.

После того как все соседние с рабочим узлы исследованы и временные отметки при необходимости изменены, по всему графу ищется узел с наименьшей временной отметкой. Этот узел помечается как постоянный и становится текущим рабочим узлом. На рис. 5.6 показаны первые шесть этапов работы алгоритма.

Чтобы понять, как работает алгоритм, посмотрим на рис. 5.6, в. На данном этапе узел E только что был отмечен как постоянный. Предположим, что существует более короткий путь, нежели ABE, например AXYZE (для некоторых X и Y). В этом случае есть две возможности — либо узел Z уже сделан постоянным, либо еще нет. Если да, значит, узел E уже проверялся, когда узел Z был сделан постоянным и, следовательно, рабочим узлом. В этом случае путь AXYZE уже исследовался.

Теперь рассмотрим случай, когда узел Z все еще помечен как временный. Если отметка узла Z больше или равна пометки узла E, путь AXYZE не может быть короче, чем путь ABE. Если же отметка узла Z меньше пометки узла E, то тогда узел Z должен был стать постоянным раньше узла E, и узел E проверялся бы с узла Z.

Этот алгоритм приведен в листинге 5.1. Глобальные переменные n и dist описывают граф и инициализируются раньше, чем вызывается shortest_path. Единственное отличие программы от описанного выше алгоритма заключается в том, что вычисление кратчайшего пути в программе начинается не от узла-источника s, а от конечного узла t.

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

Листинг 5.1. Алгоритм Дейкстры вычисления кратчайшего пути по графу

Листинг 3.7 (продолжение)

5.2.3. Заливка

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

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

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

Чтобы предотвратить неограниченный рост размера списка, можно снабдить все списки счетчиком k, показывающим, что все порядковые номера вплоть до k уже встречались. И когда приходит пакет, можно очень легко проверить, был ли он уже передан, сравнивая его порядковый номер с k; при положительном ответе такой пакет отвергается. Кроме того, не нужно хранить весь список до k, поскольку этот счетчик очень действенно подытоживает его.

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

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

5.2.4. Маршрутизация по вектору расстояний

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

Алгоритмы маршрутизации по вектору расстояний (distance vector routing) работают, опираясь на таблицы (то есть векторы), поддерживаемые всеми маршрутизаторами и содержащие сведения о кратчайших известных путях к каждому из возможных адресатов и о том, какое соединение следует при этом использовать. Для обновления данных этих таблиц производится обмен информацией с соседними маршрутизаторами. В результате маршрутизатор знает наилучший способ добраться до любого адреса назначения.

Алгоритм маршрутизации по вектору расстояний иногда называют по именам его создателей распределенным алгоритмом Беллмана—Форда (Bellman-Ford) (Bellman, 1957; Ford и Filkerson, 1962). Этот алгоритм изначально применялся в сети ARPANET и в Интернете был известен под названием RIP.

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

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

Предположим, что в качестве единицы измерения используется время задержки и этот параметр относительно каждого из соседей известен маршрутизатору. Через каждые T мс все маршрутизаторы посылают своим соседям список с приблизительными задержками для каждого получателя. Они, разумеется, также получают подобный список от всех своих соседей. Допустим, одна из таких таблиц пришла от соседа и в ней указывается, что время распространения от маршрутизатора X до маршрутизатора i равно Xi. Если маршрутизатор знает, что время пересылки до маршрутизатора равно m, тогда задержка при передаче пакета маршрутизатору i через маршрутизатор составит Xi + m. Выполнив такие расчеты для всех своих соседей, маршрутизатор может выбрать наилучшие пути и поместить соответствующие записи в новую таблицу. Обратите внимание, что старая таблица в расчетах не используется.

Процесс обновления таблицы проиллюстрирован на рис. 5.7. На рис. 5.7, а показана сеть. Первые четыре столбца на рис. 5.7, б показывают векторы задержек, полученные маршрутизатором J от своих соседей. Маршрутизатор A считает, что время пересылки от него до маршрутизатора B равно 12 мс, 25 мс до маршрутизатора C, 40 мс до D и т. д. Предположим, что маршрутизатор J измерил или оценил задержки до своих соседей A, I, H и K как 8, 10, 12 и 6 мс соответственно.

Теперь рассмотрим, как J рассчитывает свой новый маршрут к маршрутизатору G. Он знает, что задержка до A составляет 8 мс и при этом A думает, что от него до G данные дойдут за 18 мс. Таким образом, J знает, что если он станет отправлять пакеты для G через A, то задержка составит 26 мс. Аналогично, он вычисляет значения задержек для маршрутов от него до G, проходящих через остальных его соседей (I, H и K), и получает соответственно 41 (31 + 10), 18 (6+12) и 37 (31+6). Лучшим значением является 18, поэтому именно оно помещается в таблицу в запись для получателя G. Вместе с числом 18 туда же помещается обозначение линии, по которой

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

Рис. 5.7. Сеть (а); полученные от A, I, H и Kвекторы и новая таблица маршрутов для J (б)

Проблема счета до бесконечности

Установление маршрутов, соответствующих кратчайшим путям, в сети называется конвергенцией (convergence). Алгоритм маршрутизации по вектору расстояний — простой метод, позволяющий маршрутизаторам совместно вычислять кратчайшие пути. Однако на практике он обладает серьезным недостатком: хотя правильный ответ в конце концов и находится, процесс его поиска может занять довольно много времени. В частности, такой алгоритм быстро реагирует на хорошие новости и очень лениво — на плохие. Рассмотрим маршрутизатор, для которого расстояние до маршрутизатора достаточно велико. Если при очередном обмене векторами его сосед A сообщит ему, что от него до маршрутизатора X совсем недалеко, наш маршрутизатор просто переключится для передач маршрутизатору X на линию, проходящую через этого соседа. Таким образом, хорошая новость распространилась всего за один обмен информацией.

Чтобы увидеть, как быстро распространяются хорошие известия, рассмотрим линейную сеть из пяти узлов, показанную на рис. 5.8, в которой мерой расстояния служит количество транзитных участков. Предположим, что вначале маршрутизатор A выключен, и все остальные маршрутизаторы об этом знают. То есть они считают, что расстояние до A равно бесконечности.

Рис. 5.8. Проблема счета до бесконечности

Когда в сети появляется A, остальные маршрутизаторы узнают об этом с помощью обмена векторами. Для простоты будем предполагать, что где-то в сети имеется гигантский гонг, в который периодически ударяют, чтобы инициировать одновременный обмен векторами. После первого обмена B узнает, что у его соседа слева нулевая задержка при связи с A, а B помечает в своей таблице маршрутов, что A находится слева на расстоянии одного транзитного участка. Все остальные маршрутизаторы в этот момент еще полагают, что A выключен. Значения задержек для A в таблицах на этот момент показаны во второй строке на рис. 5.8, а. При следующем обмене информацией C узнает, что у B есть путь к A длиной 1, поэтому он обновляет свою таблицу, указывая длину пути до A, равную 2, но D и E об этом еще не знают. Таким образом, хорошие вести распространяются со скоростью один транзитный участок за один обмен векторами. Если самый длинный путь в сети состоит из N транзитных участков, то через N обменов все маршрутизаторы подсети будут знать о включенных маршрутизаторах и заработавших линиях.

Теперь рассмотрим ситуацию на рис. 5.8, б, в которой все связи и маршрутизаторы изначально находятся во включенном состоянии. Маршрутизаторы B, C, D и E находятся на расстоянии 1, 2, 3 и 4 транзитных участков от A соответственно. Внезапно либо A отключается, либо происходит обрыв линии между A и B (что с точки зрения одно и то же).

При первом обмене пакетами B не слышит ответа от A. К счастью, C говорит: «Не волнуйся. У меня есть путь к A длиной 2». B вряд ли догадывается, что путь от C к проходит через B. B может только предполагать, что у C около 10 выходных связей с независимыми путями к A, кратчайшая из которых имеет длину 2. Поэтому теперь B думает, что может связаться с A через C по пути длиной 3. При этом первом обмене маршрутизаторы D и E не обновляют свою информацию об A.

При втором обмене векторами C замечает, что у всех его соседей есть путь к A длиной 3. Он выбирает один из них случайным образом и устанавливает свое расстояние до A равным 4, как показано в третьей строке на рис. 5.8, б. Результаты последующих обменов векторами также показаны на этом рисунке.

Теперь должно быть понятно, почему плохие новости медленно распространяются — ни один маршрутизатор не может установить значение расстояния, более чем на

единицу превышающее минимальное значение этого расстояния, хранящееся у его соседей. Таким образом, все маршрутизаторы будут до бесконечности увеличивать значение расстояния до выключенного маршрутизатора. Количество необходимых для завершения этого процесса обменов векторами можно ограничить, если установить значение этой «бесконечности» равным длине самого длинного пути плюс 1.

Неудивительно, что эта проблема называется счетом до бесконечности (count-to-infinity). Было сделано много попыток решить ее, например можно запретить маршрутизатору сообщать о своих кратчайших путях соседям, от которых они получили эту информацию, с помощью правила расколотого горизонта с «отравляющим» ответом внесенного в RFC 1058. Однако на практике все эти эвристические правила с красивыми названиями оказались абсолютно бесполезными. Суть проблемы заключается в том, что когда Х сообщает Y о том, что у него есть какой-то путь, у Y нет никакой возможности узнать, входит ли он сам в этот путь.

5.2.5. Маршрутизация с учетом состояния линий

Маршрутизация на основе векторов расстояний использовалась в сети ARPANET вплоть до 1979 года, когда ее сменил алгоритм маршрутизации с учетом состояния линий. Отказаться от прежнего алгоритма пришлось в первую очередь потому, что при изменении топологии сети алгоритм слишком долго приходил к устойчивому состоянию (вследствие проблемы счета до бесконечности). В результате он был заменен на совершенно новый алгоритм, ныне называемый маршрутизацией с учетом состояния линий (link state routing). Сейчас в крупных сетях и сети Интернет используются его варианты — алгоритмы маршрутизации IS-IS и OSPF.

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

1)    обнаруживать своих соседей и узнавать их сетевые адреса;

2)    задавать метрику расстояния или стоимости связи с каждым из своих соседей;

3)    создавать пакет, содержащий всю собранную информацию;

4)    посылать этот пакет всем маршрутизаторам и принять все пакеты, отправленные другими маршрутизаторами;

5)    вычислять кратчайший путь ко всем маршрутизаторам.

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

Знакомство с соседями

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

Когда два или более маршрутизаторов соединены с помощью широковещательной связи (например, коммутатора, кольцевой сети или классической сети Ethernet), ситуация несколько усложняется. На рис. 5.9, а изображена широковещательная ЛВС, к которой напрямую подключены три маршрутизатора: A, C и F. Каждый из них, как показано на рисунке, соединен также с одним или несколькими дополнительными маршрутизаторами.

Рис. 5.9. Широковещательная ЛВС: а — девять маршрутизаторов и широковещательная локальная сеть; б — графовая модель той же системы

Широковещательная ЛВС обеспечивает связь между каждой парой подключенных маршрутизаторов. Однако моделирование такой сети в виде системы связей «точка-точка» существенно увеличивает размер топологии и приводит к нерациональной передаче сообщений. Более подходящий способ моделирования локальной сети состоит в том, что ЛВС рассматривается в виде узла графа, как и маршрутизаторы. Это показано на рис. 5.9, б. На рисунке сеть изображена в виде искусственного узла N, с которым соединены маршрутизаторы A, C и F. Для исполнения роли N в протоколе маршрутизации выбирается один из маршрутизаторов сети, который называется отмеченным маршрутизатором (designated router). Возможность передачи пакетов от A к C по локальной сети отражается здесь наличием пути ANC.

Задание стоимости связи

Алгоритм маршрутизации с учетом состояния линии требует, чтобы каждая связь обладала метрикой расстояния или стоимости, необходимой для вычисления кратчайшего пути. Стоимость пути до соседних маршрутизаторов может быть задана автоматически или определена оператором сети. Чаще всего стоимость обратно пропорциональна пропускной способности связи. Так, сеть Ethernet со скоростью 1 Гбит/с может иметь стоимость 1, а Ethernet со скоростью 100 Мбит/с — стоимость 10. Благодаря этому в качестве наилучших путей будут выбираться пути с более высокой пропускной способностью. Если узлы сети находятся на большом расстоянии друг от друга, при вычислении стоимости может учитываться задержка соединения. В таком случае в качестве наилучших путей будут выбираться более короткие. Наиболее прямой способ определить эту задержку заключается в посылке по линии специального пакета ECHO, на который другая сторона обязана немедленно ответить. Измерив время двойного оборота этого пакета и разделив его на два, отправитель получает приемлемую оценку задержки.

Создание пакетов состояния линий

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

Рис. 5.10. Сеть (а); пакеты состояния линий для этой сети (б)

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

Распространение пакетов состояния линий

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

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

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

Во-вторых, если маршрутизатор выйдет из строя, будет потерян его порядковый номер. Если он будет снова загружен с нулевым порядковым номером, следующий отправленный с него пакет будет проигнорирован как устаревший.

В-третьих, может произойти искажение порядкового номера — например, вместо номера 4 будет принято число 65 540 (ошибка в одном бите); в этом случае пакеты с 5-го по 65 540-й будут игнорироваться некоторыми маршрутизаторами как устаревшие.

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

Для повышения надежности этого алгоритма используются некоторые усовершенствования. Когда пакет состояния линий приходит на маршрутизатор для заливки, он не ставится сразу в очередь на отправку. Вместо этого он сохраняется в течение некоторого периода времени в области промежуточного хранения на случай появления новых связей или разрыва старых. Если за это время от того же отправителя успевает прийти еще один пакет, маршрутизатор сравнивает их порядковые номера. Более старый пакет удаляется. Если номера одинаковые, то удаляется дубликат. Для защиты от ошибок на линиях связи получение всех пакетов состояния линий подтверждается. Структура данных, используемая маршрутизатором B для работы с сетью, изображенной на рис. 5.10, а, показана на рис. 5.11. Каждая строка здесь соответствует недавно полученному, но еще не полностью обработанному пакету состояния линий. В таблице записываются адрес отправителя, порядковый номер, возраст и данные. Кроме того, в таблице содержатся флаги рассылки и подтверждений для каждой из трех линий маршрутизатора BA, C и F, соответственно). Флаги отсылки означают, что этот пакет следует отослать по соответствующей связи. Флаги подтверждений означают, что нужно подтвердить получение этого пакета по данной линии.

Рис. 5.11. Буфер пакетов маршрутизатора B c рисунка 5.10

Как видно из рис. 5.11, пакет состояния линий от маршрутизатора A пришел напрямую, поэтому он должен быть отправлен маршрутизаторам C и F, а подтверждение о его получении следует направить маршрутизатору A, что и показывают флаговые биты. Аналогично, пакет от Fследует переслать маршрутизаторам A и C, а F отослать подтверждение.

Однако ситуация с третьим пакетом, полученным от маршрутизатора E, отличается. Он приходит дважды, по линиям EAB и EFB. Следовательно, его нужно отослать только C, но подтверждения необходимо выслать и A и F, как указывают биты.

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

Вычисление новых маршрутов

Собрав полный комплект пакетов состояния линий, маршрутизатор может построить полный граф сети, так как он располагает данными обо всех линиях. На самом деле, каждая линия представлена даже дважды, по одному значению для каждого направления. У разных направлений может быть разная стоимость. Поэтому результаты вычисления кратчайшего пути от A до B и от B до A могут не совпадать.

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

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

Маршрутизация с учетом состояния линий широко применяется в современных сетях, поэтому следует сказать несколько слов о некоторых примерах протоколов. Многие интернет-провайдеры используют протокол маршрутизации с учетом состояния линий IS-IS (Intermediate System to Intermediate System связь между промежуточными системами) (Oran, 1990). Он был разработан достаточно давно для сети DECnet и был впоследствии принят Международной организацией по стандартизации ISO для использования вместе с протоколами OSI. После этого он был модифицирован для поддержки также и других протоколов, в частности, IP. Еще один из наиболее известных протоколов маршрутизации с учетом состояния линий — OSPF (Open Shortest Path First открытый алгоритм предпочтительного выбора кратчайшего маршрута). Он был разработан Специальной комиссией интернет-разработок (IETF) через несколько лет после IS-IS и включал многие новшества, применявшиеся при создании IS-IS. К этим новшествам относятся метод саморегуляции лавинного потока обновлений информации о состоянии линий, концепция отмеченного маршрутизатора в локальной сети, а также метод вычисления и поддержки расщепления пути и умножения метрик. Соответственно, между протоколами IS-IS и OSPF нет почти никакой разницы. Наиболее существенное различие между ними заключается в том, что в IS-IS возможна одновременная поддержка нескольких протоколов сетевого уровня (например, IP, IPX и AppleTalk). OSPF не обладает таким свойством, и это оказывается преимуществом в больших многопротокольных средах. Более подробно о протоколе OSPF будет рассказано в разделе 5.6.6.

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

5.2.6. Иерархическая маршрутизация

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

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

В очень больших сетях двухуровневой иерархии может оказаться недостаточно. Может потребоваться группировать регионы в кластеры, кластеры в зоны, зоны в группы и т. д., пока у нас не иссякнет фантазия на названия для новых образований. В качестве примера многоуровневой иерархии рассмотрим маршрутизацию пакета, пересылаемого из университета Беркли (Berkeley), штат Калифорния в Малинди (Malindi) в Кении. Маршрутизатор в Беркли знает детали топологии в пределах Калифорнии, но трафик, направляющийся за пределы штата, он посылает маршрутизатору в Лос-Анджелесе. Маршрутизатор в Лос-Анджелесе может выбрать прямой маршрут для трафика в пределах США, но все пакеты, направляемые за рубеж, переправляет в Нью-Йорк. Нью-йоркский маршрутизатор направит трафик на маршрутизатор страны назначения, ответственный за прием трафика из-за границы. Он может располагаться, например, в Найроби. Наконец, направляясь вниз по дереву иерархии уже в пределах Кении, пакет попадет в Малинди.

На рис. 5.12 приведен количественный пример маршрутизации в двухуровневой иерархии с пятью регионами. Полная таблица маршрутизатора 1A, как показано на рис. 5.12, б, состоит из 17 записей. При использовании иерархической маршрутизации, как показано на рис. 5.12, в, таблица, как и прежде, содержит сведения обо всех локальных маршрутизаторах, но записи обо всех остальных регионах концентрируются в пределах одного маршрутизатора, поэтому трафик во второй регион по-прежнему пойдет по линии 1B-2A, а во все остальные регионы — по линии 1C-3B. При иерархической маршрутизации размер таблицы маршрутов уменьшается с 17 до 7 строк. Чем крупнее выбираются регионы, тем больше экономится места в таблице.

Рис. 5.12. Иерархическая маршрутизация

К сожалению, этот выигрыш памяти не достается бесплатно. Платой является увеличение длины пути. Например, наилучший маршрут от 1A до 5C проходит через регион 2, однако при использовании иерархической маршрутизации весь трафик в регион 5 направляется через регион 3, поскольку так лучше для большинства адресатов в регионе 5.

Когда единая сеть становится очень большой, возникает интересный вопрос: сколько уровней должна иметь иерархия? Для примера рассмотрим сеть с 720 маршрутизаторами. Если иерархии нет, то каждому маршрутизатору необходимо поддерживать таблицу из 720 строк. Если сеть разбить на 24 региона по 30 маршрутизаторов в каждом регионе, тогда каждому маршрутизатору потребуется 30 локальных записей плюс 23 записи об удаленных регионах, итого 53 записи. При выборе трехуровневой иерархии, состоящей из 8 кластеров по 9 регионов из 10 маршрутизаторов, каждому маршрутизатору понадобится 10 строк в таблице для локальных маршрутизаторов, 8 строк для маршрутизации в другие регионы в пределах своего кластера, плюс 7 строк для удаленных кластеров, итого 25 строк. Камоун (Kamoun) и Кляйнрок (Kleinrock) в 1979 году показали, что оптимальное количество уровней иерархии для сети, состоящей из N маршрутизаторов, равно ln N. При этом потребуется e ln N записей для каждого маршрутизатора. Они также показали, что увеличение длины эффективного среднего пути, вызываемое иерархической маршрутизацией, довольно мало и обычно является приемлемым.

5.2.7. Широковещательная маршрутизация

В некоторых приложениях хостам требуется посылать сообщения на множество хостов или даже на все сразу. Можно привести такие примеры, как распространение прогнозов погоды, обновление биржевых курсов ценных бумаг, радиопрограммы в прямом эфире. Эффективнее всего отправлять соответствующие данные широковещательным способом, предоставляя возможность получить их всем заинтересованным хостам. Итак, широковещанием (broadcasting) называется рассылка пакетов по всем пунктам назначения одновременно. Для ее реализации применяются разнообразные методы.

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

Один из более совершенных алгоритмов называется многоадресной маршрутизацией (multidestination routing), при которой в каждом пакете содержится либо список адресатов, либо битовая карта, показывающая предпочитаемые хосты назначения. Когда такой пакет прибывает в маршрутизатор, последний проверяет список, содержащийся в пакете, определяя набор выходных линий, которые потребуются для дальнейшей рассылки. (Линия может потребоваться в том случае, если она входит в оптимальный путь к какому-то из адресатов списка.) Маршрутизатором создается копия пакета для каждой из используемых исходящих линий. В нее включаются только те адресаты, для доступа к которым требуется данная линия. Таким образом, весь список рассылки распределяется между исходящими линиями. После определенного числа пересылок каждый из пакетов будет содержать только один адрес назначения, как и обычный пакет. Многоадресная маршрутизация подобна использованию индивидуально адресуемых пакетов с той разницей, что в первом случае из нескольких пакетов, следующих по одному и тому же маршруту, только один «платит полную стоимость», а остальные едут бесплатно. В таком случае пропускная способность используется более эффективно. Однако этот метод все же требует начальных сведений обо всех адресах назначения, и, кроме того, чтобы понять, куда отправить один многоадресный пакет, маршрутизатор должен выполнить столько же действий, сколько и при отправке набора отдельных пакетов.

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

Идея продвижения по встречному пути (reverse path forwarding) замечательно проста и изящна (Dadal, Metcalfe, 1978). Когда прибывает широковещательный пакет, маршрутизатор проверяет, используется ли та связь, по которой он прибыл, для нормальной передачи пакетов источнику широковещания. В случае положительного ответа велика вероятность того, что широковещательный пакет прибыл по наилучшему маршруту и является, таким образом, первой копией, прибывшей на маршрутизатор. Тогда маршрутизатор рассылает этот пакет по всем связям, кроме той, по которой он прибыл. Однако если широковещательный пакет прибывает от того же источника по другой связи, он отвергается как вероятный дубликат.

Рис. 5.13. Продвижение по встречному пути: а — сеть; б — входное дерево; в — дерево, построенное методом продвижения по встречному пути

Пример работы алгоритма продвижения по встречному пути показан на рис. 5.13. Слева изображена сеть, посередине — входное дерево для маршрутизатора I этой сети. На первом транзитном участке маршрутизатор I посылает пакеты маршрутизаторам F, H, J и N, являющимся вторым ярусом дерева. Все эти пакеты прибывают к ним по предпочитаемым линиям до I (по пути, совпадающему с входным деревом), что обозначается кружками вокруг символов на рис. 5.13, в. На втором этапе пересылки формируются восемь пакетов — по два каждым маршрутизатором, получившим пакет после первой пересылки. Все восемь пакетов попадают к маршрутизаторам, не получавшим ранее пакетов, а пять из них приходят по предпочитаемым линиям. Из шести пакетов, формируемых на третьем транзитном участке, только три прибывают по предпочитаемым линиям (на маршрутизаторы C, E и K). Остальные оказываются дубликатами. После пяти транзитных участков широковещание заканчивается с общим количеством переданных пакетов, равным 23, тогда как при использовании входного дерева потребовалось бы 4 транзитных участка и 14 пакетов.

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

Последний алгоритм широковещательной маршрутизации выигрывает перед алгоритмом продвижения по встречному пути. Он в явном виде использует входное дерево или любое другое связующее дерево для маршрутизатора, инициировавшего широковещание. Связующее дерево (spanning tree) представляет собой подмножество сети, включающее в себя все маршрутизаторы, но не содержащее замкнутых путей. Если каждый маршрутизатор знает, какие из его линий принадлежат связующему дереву, он может отправить приходящий пакет по всем линиям связующего дерева, кроме той, по которой пакет прибыл. Такой метод оптимальным образом использует пропускную способность сети, порождая минимальное количество пакетов, требующихся для выполнения работы. Так, если в примере на рис. 5.13 в качестве связующего дерева использовать входное дерево (рис. 5.13, б), минимальное число пакетов, необходимое для широковещания, составляет 14. Единственной проблемой этого метода является то, что каждому маршрутизатору необходимо обладать информацией о связующем дереве. Иногда такая информация доступна (например, в случае маршрутизации с учетом состояния линий все маршрутизаторы обладают полными сведениями о топологии сети и поэтому могут вычислить связующее дерево), но иногда — нет (при маршрутизации по векторам расстояний).

5.2.8. Многоадресная рассылка

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

Передача сообщения членам такой группы называется многоадресной рассылкой (multicasting), а использующийся при этом алгоритм — многоадресной маршрутизацией (multicast routing). Любая схема многоадресной рассылки предполагает возможность создания и удаления групп и определения списка маршрутизаторов, являющихся членами данной группы. Реализация данных задач, однако, не интересует алгоритм маршрутизации. Пока мы будем считать, что каждая группа определяется адресом рассылки и что каждый маршрутизатор знает, в какие группы он входит. Мы вернемся к вопросу принадлежности к группам, когда будем говорить о сетевом уровне Интернета в разделе 5.6. Схемы многоадресной рассылки основываются на принципах широковещательной маршрутизации, о которой мы уже говорили: пакеты, предназначенные членам группы, пересылаются по связующему дереву, и при этом ставится задача эффективного использования пропускной способности сети. Однако выбор наилучшего связующего дерева зависит от того, является ли группа плотной (когда получатели занимают большую часть всей сети) или разреженной (когда большая часть сети не принадлежит группе). В этом разделе мы рассмотрим оба случая.

Если группа является плотной, применение широковещания является неплохой идеей, поскольку в результате пакет будет успешно отправлен во все части сети. Однако минус этого алгоритма в том, что пакет получат и те маршрутизаторы, которые не являются членами группы. Решение, предложенное Дирингом и Черитоном (Deering, Cheriton, 1990), состоит в том, чтобы удалить из связующего дерева ветви, не ведущие к членам группы. В результате получается эффективное многоадресное связующее дерево.

Для примера рассмотрим две группы, 1 и 2, в сети, изображенной на рис. 5.14, а. Как показано на рисунке, некоторые маршрутизаторы соединены с хостами, принадлежащими к одной или обеим группам. Связующее дерево для самого левого маршрутизатора показано на рис. 5.14, б. Такое дерево может быть использовано для широковещания, однако (как это видно на примере двух усеченных вариантов дерева, приведенных далее) для многоадресной рассылки оно оказывается избыточным. На рис. 5.14, в удалены все связи, не ведущие к хостам, являющимся членами группы 1. В результате получается многоадресное связующее дерево, по которому самый левый маршрутизатор может отправлять пакеты группе 1. Пакеты передаются исключительно по такому дереву — этот способ оказывается гораздо более экономичным, чем широковещание: новое дерево использует 7 связей вместо 10. На рис. 5.14, г показано усеченное многоадресное связующее дерево для группы 2. Оно использует 5 связей, что доказывает его эффективность. Следует обратить внимание на то, что для разных групп используются разные связующие деревья.

Рис. 5.14. Многоадресная рассылка: а — сеть; б — связующее дерево для самого левого маршрутизатора; в — многоадресное дерево для группы 1; г — многоадресное дерево

для группы 2

Существует несколько способов усечения связующего дерева. Простейший способ может применяться при использовании маршрутизации с учетом состояния линий, когда каждому маршрутизатору известна полная топология сети, в том числе и состав групп. В таком случае каждый маршрутизатор может построить собственное усеченное связующее дерево для каждого отправителя, сначала создав обычное входное дерево, а затем удалив из него все связи, не соединяющие входной (корневой) узел с членами данной группы. Одним из протоколов маршрутизации с учетом состояния линий, работающих по такому принципу, является MOSPF (Multicast OSPPF многоадресный OSPF) (Moy, 1994).

При маршрутизации по векторам расстояний может быть применена другая стратегия усечения дерева. Для многоадресной рассылки здесь применяется алгоритм продвижения по встречному пути. Когда многоадресное сообщение получает маршрутизатор, у которого нет хостов, входящих в группу, и линий связи с другими маршрутизаторами, принимающими сообщения для данной группы, он может ответить сообщением PRUNE (отсечь), информируя соседа, отправившего сообщение, о том, что сообщения для данной группы ему больше посылать не нужно. Такой же ответ может дать маршрутизатор, у которого нет хостов, входящих в группу, если он получил сообщение PRUNE по всем линиям, по которым он осуществил многоадресную рассылку. В результате связующее дерево постепенно рекурсивно усекается. Примером протокола многоадресной маршрутизации, работающего по такому принципу, является DVRMP (Distance Vector Multicast Routing Protocol протокол многоадресной маршрутизации по вектору расстояний) (Waitzman и др., 1988).

Усечение позволяет строить эффективные связующие деревья, состоящие только из тех связей, которые необходимы для соединения с членами группы. Недостаток данного метода заключается в том, что он требует от маршрутизаторов выполнения большого количества операций, особенно в больших сетях. Предположим, что в сети есть n групп, каждая из которых в среднем состоит из m членов. На каждом маршрутизаторе и для каждой группы должно храниться m усеченных связующих деревьев, то есть mn деревьев для всей сети. К примеру, на рис. 5.14, в изображено связующее дерево, по которому самый левый маршрутизатор отправляет пакеты группе 1. Связующее дерево, по которому самый правый маршрутизатор отправляет пакеты группе 1 (оно не показано на рисунке), будет выглядеть по-другому, поскольку пакеты будут передаваться непосредственно членам группы, а не через узлы в левой части графа. А это значит, что выбор направления, в котором маршрутизаторы должны передавать пакеты для группы 1, зависит от того, какой узел является отправителем. При большом количестве групп и отправителей для хранения всех деревьев потребуется много памяти.

Альтернативный метод при построении отдельного связующего дерева для группы использует деревья с корнем в ядре (core-based trees)(Ballardie и др., 1993). Согласно этому методу, все маршрутизаторы выбирают общий корень (также называемый ядром — core или точкой встречи — rendezvouz point), а для построения дерева все члены группы отправляют в этот корень специальный пакет. Конечное дерево формируется из путей, пройденных этими пакетами. На рис. 5.15, а показано такое дерево с основанием в ядре, построенное для группы 1. Для пересылки пакета этой группе отправитель передает сообщение ядру, откуда оно уже рассылается по дереву. Пример такой работы алгоритма продемонстрирован на рис. 5.15, б для отправителя, расположенного в правой части сети. Однако производительность этого метода может быть улучшена: дело в том, что для многоадресной рассылки не обязательно, чтобы пакеты, предназначенные для группы, приходили в ядро. Как только пакет достигает дерева, он может быть передан как в направлении корня, так и в любом другом направлении. Так алгоритм работает для отправителя, расположенного вверху рис. 5.15, б.

Рис. 5.15. Дерево с основанием в сердцевине для группы 1 (а); рассылка для группы 1 (б)

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

Следует также отметить, что использование общего дерева позволяет существенно снизить затраты на хранение информации, а также уменьшить число отправленных сообщений и объем вычислений. Для каждой группы маршрутизатор должен хранить не m деревьев, а лишь одно. Кроме того, маршрутизаторы, не являющиеся частью дерева, не участвуют в передаче сообщений группе. Поэтому алгоритмы на основе общих деревьев (в частности, деревьев с основанием в ядре) используются при широковещании для разреженных групп в сети Интернет, являясь частью популярных протоколов, таких как PIM (Protocol Independent Multicast — многоадресная рассылка, не зависящая от протокола) (Fenner и др., 2006).

5.2.9. Произвольная маршрутизация

До сих пор мы рассматривали такие модели предоставления информации, в которых источник отправляет сообщение на один адрес (одноадресная рассылка — unicast), на все адреса (широковещание) или группе адресов (многоадресная рассылка). Иногда используется еще одна модель под названием произвольная рассылка (anycast). При такой рассылке пакет отправляется ближайшему члену группы (Partridge и др., 1993). Методы нахождения соответствующих путей называются произвольной маршрутизацией (anycast routing).

Зачем нам может понадобиться произвольная рассылка? Иногда узлы предоставляют услугу (например, сообщают время суток или передают контент), для которой важно одно: чтобы информация была правильной; при этом не имеет значения, какой узел ее предоставил — с этой задачей справился бы любой узел. Пример использования свободной рассылки в сети Интернет — DNS, о которой мы поговорим в главе 7.

К счастью, нам не придется придумывать новые алгоритмы для произвольной маршрутизации: стандартные методы — маршрутизация по вектору расстояния и маршрутизация с учетом состояния линий — позволяют создавать маршруты для произвольной рассылки. Предположим, что нам нужно передать данные членам группы 1. Вместо различных адресов все члены группы получат одинаковый адрес — «1». Алгоритм маршрутизации по вектору расстояния распределит векторы обычным способом, и узлы выберут кратчайший путь к адресу 1. В результате узлы отправят данные на ближайшее устройство с адресом 1. Соответствующие маршруты показаны на рис. 5.16 а. Этот метод работает успешно потому, что протокол маршрутизации не знает о существовании нескольких устройств с адресом 1, а значит, он считает их всех одним узлом, как показано в топологии на рис. 5.16, б.

Рис. 5.16. Произвольная маршрутизация: а — маршруты для свободной рассылки; б — топология с точки зрения протокола маршрутизации

Такой метод будет работать и для маршрутизации с учетом состояния линий. Здесь, правда, следует добавить, что протокол маршрутизации не обязательно должен находить кажущиеся кратчайшими пути, проходящие чрез узел 1. Это привело бы к «прыжку через гиперпространство», потому что экземпляры узла 1 на самом деле расположены в различных частях сети. Однако сейчас протоколы маршрутизации с учетом состояния линий различают маршрутизаторы и хосты. Мы не говорили об этом раньше, поскольку в этом не было явной необходимости.

5.2.10. Алгоритмы маршрутизации для мобильных хостов

Миллионы людей пользуются компьютерами на ходу. Сюда относятся ситуации фактического передвижения, такие как использование беспроводных устройств в движущемся автомобиле, а также ситуации мобильного использования портативных компьютеров в нескольких разных местах. Термин мобильные хосты (mobile hosts) мы будем использовать для обозначения и тех, и других ситуаций, противопоставляя их стационарным, никогда не перемещающимся хостам. В последнее время люди все больше хотят оставаться в сети независимо от того, в какой части земного шара они находятся, и делать это так же легко, как дома. Такие мобильные хосты вызывают дополнительную сложность: чтобы направить пакет к мобильному хосту, сеть должна сначала найти его.

Здесь мы будем рассматривать модель мира, в которой у всех хостов есть постоянное домашнее местоположение (home location), которое никогда не меняется. У каждого хоста также есть постоянный домашний адрес, которым можно воспользоваться для определения домашнего местоположения, аналогично тому, как телефонный номер 1-212-5551212 обозначает США (страна с кодом 1) и Манхеттен (212). Целью маршрутизации в системах с мобильными хостами является обеспечение возможности передачи пакетов мобильным хостам с помощью их постоянных домашних адресов. При этом пакеты должны эффективно достигать хостов, независимо от их расположения. Самое сложное здесь, конечно, — найти хост.

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

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

В основе мобильной маршрутизации в сети Интернет и сетях сотовой связи лежит следующая идея: мобильный хост должен сообщать о том, где он находится, хосту, имеющему домашнее местоположение. Этот хост, выполняющий операции от имени мобильного хоста, называется внутренним агентом (home agent). Как только он узнает текущее местоположение мобильного хоста, он может перенаправлять пакеты, которые должны быть ему доставлены.

Рисунок 5.17 наглядно демонстрирует работу мобильной маршрутизации. Отправитель из северо-западного города Сиэтла хочет отправить пакет хосту, который обычно находится по другую сторону США, в Нью-Йорке. Нас интересует ситуация, при которой мобильный хост располагается не дома. Временно он находится в Сан-Диего. Для работы в сети мобильный хост в Сан-Диего должен получить локальный сетевой адрес. Это обычная процедура; о том, как она работает для сети Интернет, мы поговорим позже. Такой локальный адрес называется адресом для передачи (care of address). Как только мобильный хост узнает этот адрес, он может сообщить внутреннему агенту свое местонахождение. Для этого он отправляет внутреннему агенту регистрационное сообщение (этап 1), содержащее адрес для передачи. На рис. 5.17 это сообщение выделено пунктирной линией, чтобы показать, что оно является управляющим, а не информационным.

Далее отправитель посылает пакет с данными на мобильный хост с помощью постоянного адреса (этап 2). Сеть передает этот пакет на домашнее местоположение хоста, так как именно ему принадлежит этот домашний адрес. В Нью-Йорке внутренний агент перехватывает этот пакет, поскольку мобильный хост находится далеко от дома. Затем он формирует пакет с новым заголовком (инкапсулирует encapsulates, или, как иногда говорят, «заворачивает» — wraps) и отправляет все это на адрес для передачи (этап 3). Такой прием называется туннелированием (tunneling). Поскольку он имеет важное значение в работе сети Интернет, далее мы поговорим о нем более подробно.

Когда этот пакет прибывает на адрес для передачи, мобильный хост разворачивает пакет и считывает данные, полученные от отправителя. Далее мобильный хост напрямую посылает отправителю ответный пакет (этап 4). Весь этот путь называется треугольной маршрутизацией (triangle routing); он может быть непрямым, если удаленное местоположение расположено на большом расстоянии от домашнего местоположения. На этапе 4 отправитель может узнать текущий адрес для передачи. Последующие пакеты могут направляться напрямую на мобильный хост, передаваясь по туннелю на адрес для передачи (этап 5), полностью минуя домашний адрес мобильного пользователя. Если соединение будет прервано из-за перемещения мобильного устройства, для связи с ним всегда можно использовать домашний адрес.

Рис. 5.17. Маршрутизация пакетов мобильным хостам

Мы не уделили внимания еще одному важному аспекту: безопасности. Как правило, когда хост или маршрутизатор получает сообщение вида «Начиная с этого момента, пожалуйста, пересылайте мне всю почту, адресуемую Стефани», у него могут возникнуть вопросы — например, с кем он разговаривал, соглашаться или нет на данное предложение. Поэтому, для того чтобы достоверность сообщений можно было проверить с помощью криптографических протоколов (о которых мы поговорим в главе 8), в сообщения добавляется информация о безопасности.

Существует много различных схем мобильной маршрутизации. Алгоритм, представленный выше, основан на мобильности IPv6 — той форме мобильности, которая используется в сети Интернет (Джонсон и др., 2004), а также в IP-сетях сотовой связи, таких как UMTS. Для простоты в нашем примере отправитель рассматривался как стационарный узел, однако алгоритм позволяет обоим узлам быть мобильными хостами. Или же хост может быть частью мобильной сети, например сети в самолете. Такое расширение базовой схемы не требует дополнительных действий со стороны хостов (Devarapalli и др., 2005).

В некоторых схемах используется внешний (то есть удаленный) агент — это то же самое, что и внутренний агент, только с внешним расположением; аналогом внешнего агента в сетях сотовой связи является VLR (Visitor Location Register, гостевой регистр местоположения). Однако в большинстве более новых схем внешний агент не требуется; мобильные хосты сами являются своими внешними агентами. В любом случае, знание временного местоположения мобильного хоста ограничивается небольшим числом хостов (например, мобильное устройство, внутренний агент и отправители), поэтому маршрутизаторам крупной сети не придется повторно вычислять маршруты.

Более подробную информацию о мобильной маршрутизации можно найти в работах Perkins (1998, 2002) и Snoeren и Balakrishnan (2000).

5.2.11. Маршрутизация в произвольных сетях

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

Во всех подобных случаях каждый узел использует беспроводное соединение и выступает одновременно в качестве маршрутизатора и хоста. Сети, состоящие из узлов, волею судеб оказавшихся недалеко друг от друга, называются произвольными сетями (ad hoc networks) или мобильными произвольными сетями (MANET Mobile Ad hoc NETworks). Давайте их вкратце рассмотрим. Более подробную информацию можно найти в книге (Perkins, 2001).

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

Известно множество алгоритмов выбора маршрута для произвольных сетей. Однако поскольку по сравнению с мобильными сетями произвольные сети пока не так широко используются на практике, не ясно, какие из этих протоколов наиболее удобны. Для примера рассмотрим один из наиболее популярных — алгоритм AODV (Ad hoc On-demand Distance Vector маршрутизация по требованию в произвольных сетях на основе вектора расстояний). Об этом можно прочитать у (Perkins и Royer, 1999). AODV является родственником метода векторов расстояний, адаптированным для работы в мобильной среде, где узлы обычно имеют ограниченную пропускную способность и время работы от автономных элементов питания. Давайте посмотрим, как этот алгоритм вычисляет маршруты и следит за их изменением.

Построение маршрута

В AODV маршруты к адресу назначения вычисляются «по требованию», то есть только тогда, когда кто-то хочет отправить пакет на этот адрес. Это позволяет избежать выполнения лишней работы: если топология сети изменится, а маршрут еще не использовался, маршрут не придется вычислять дважды. Топология произвольной сети в любой момент может быть описана с помощью графа соединенных друг с другом узлов. Два узла считаются соединенными (то есть между ними проведена дуга), если они могут связываться напрямую посредством радио. Для наших целей вполне подойдет простая, но адекватная модель, в которой каждый узел может связаться со всеми узлами, находящимися в пределах его зоны охвата. На практике сети устроены более сложным образом: соединению могут препятствовать здания, холмы и т. д.; в сети также возможны ситуации, когда узел А соединен с В, но В не соединен с А, поскольку у одного из них может быть более мощный передатчик, чем у другого. Однако для простоты мы будем считать, что все соединения симметричны.

Для описания алгоритма рассмотрим недавно сформированную произвольную сеть, изображенную на рис. 5.18. Предположим, что процессу, запущенному на узле А, необходимо отправить пакет на узел I. Алгоритм AODV на каждом узле ведет таблицу векторов расстояния, доступ к которой осуществляется с помощью поля адреса. Таблица содержит информацию об адресате, в том числе адрес ближайшего соседа, которому необходимо переслать пакет, чтобы он мог достичь пункта назначения. Сначала А просматривает эту таблицу и не находит записи для I. Значит, нужно найти маршрут, ведущий к этому узлу. Итак, алгоритм начинает заниматься поисками маршрутов только тогда, когда они реально требуются. Это и делает его алгоритмом «по требованию».

Рис. 5.18. Произвольная сеть: а — зона широковещания А; б — состояние после получения его узлами В и D; в — состояние после получения его узлами C, Fи G; г — состояние после получения его узлами E, H и I. Затененными кружочками обозначены новые получатели. Пунктиром показаны возможные обратные маршруты. Сплошными линиями показан построенный маршрут

Для поиска Iузел Агенерирует пакет запроса маршрута ROUTE REQUEST и распространяет его по сети методом заливки (см. раздел 5.2.3). На рис. 5.18, апоказано, что этот пакет достигает узлов Bи D. Далее каждый узел повторно передает запрос, который в результате достигает узлов F, Gи C(рис. 5.18, в) и узлов H, Eи I(рис. 5.18, г). Чтобы избавиться от лишних копий пакета при заливке, используется порядковый номер. Так, например, Dне принимает передачу от B(рис. 5.18, в), так как он уже передал запрос. Наконец запрос достигает узла I, который создает пакет ROUTE REPLY. Этот пакет пересылается отправителю по тому же пути, по которому он пришел. Чтобы это было возможно, каждый узел должен помнить, какой узел передал ему запрос. Информация об обратном маршруте, хранящаяся в памяти узлов, показана на рис. 5.18, б-г стрелками. При передаче запроса каждый узел также увеличивает значение счетчика транзитных участков. Это позволяет понять, насколько далеко от адреса назначения расположен узел. Ответы сообщают каждому отдельному узлу, какому из соседей следует передавать пакет, предназначенный для данного адреса: тому узлу, от которого пришел ответ. Во время обработки ответа узлы Gи Dзаписывают сведения о наилучшем маршруте в таблицы маршрутизации. Когда ответ достигает узла A, появляется новый маршрут — ADGI.

В больших сетях алгоритмом генерируется много широковещательных пакетов даже для адресатов, расположенных достаточно близко друг к другу. Чтобы уменьшить издержки, область широковещания может быть ограничена полем Время жизни (Time to live) IP-пакета. Это поле устанавливается отправителем и декрементируется при каждой пересылке. Когда его значение становится равным 0, пакет отвергается, а не распространяется дальше. При этом процесс поиска пути немного изменяется. Для обнаружения адресата отправитель рассылает пакет запроса маршрута со Временем жизни, равным 1. Если в течение разумного времени ответ не приходит, посылается еще один запрос со Временем жизни, равным 2. И так далее. Таким образом, поиск, начавшийся в какой-то локальной области, все больше расширяет свой охват.

Обслуживание маршрута

Поскольку узлы могут перемещаться и выключаться, топология сети может изменяться совершенно спонтанно. Например, если на рис. 5.18 узел Gвыключится, Ане поймет, что путь к I (ADGI) больше не может быть реализован. Алгоритму нужно как-то с этим бороться. Периодически все узлы рассылают сообщение приветствия Hello. Ожидается, что все узлы, будучи истинными джентльменами, ответят на него. Если ответ не приходит, значит, сосед вышел из зоны действия или вышел из строя и больше не связан с данным узлом. Аналогичным образом, если он пытается послать пакет соседу, который не отвечает, он узнает, что связь с ним недоступна.

Эта информация используется для удаления нерабочих путей. Для каждого из возможных адресатов каждый узел Nхранит историю о том, какие активные соседи снабжали узел пакетами для данных адресатов в течение последних AT секунд.

Когда какой-либо из соседей узла N становится недоступным, узел N проверяет свою таблицу маршрутизации — ведь теперь нужно понять, к каким адресатам лежал путь через ушедший узел. Всем оставшимся активным соседям сообщается, что такие пути больше нельзя использовать и их следует удалить из таблиц маршрутизации. В нашем примере D удаляет из своей таблицы маршрутизации записи для G и I и сообщает об этом A, который в свою очередь удаляет I. В общем случае активные соседи передают эти новости своим активным соседям и т. д., пока все пути, зависевшие от ушедшего узла, не будут удалены из всех таблиц.

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

Чтобы обеспечить быструю конвергенцию, маршрутам присваиваются порядковые номера, контролируемые получателем. Порядковый номер получателя — своего рода логические часы. Получатель увеличивает этот номер каждый раз при отправке нового пакета ROUTE REPLY. Чтобы запросить новый маршрут, отправитель добавляет в пакет ROUTE REQUEST порядковый номер получателя для последнего использовавшегося маршрута: это может быть или порядковый номер только что удаленного маршрута, или 0, то есть исходное значение. Запрос будет передаваться широковещательным способом до тех пор, пока не будет найден маршрут с большим порядковым номером. Промежуточные узлы сохраняют маршруты, имеющие больший порядковый номер или меньшее число промежуточных узлов для текущего порядкового номера.

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

Пока мы рассмотрели только один маршрут: от A до I. Для большей экономии ресурсов построение и обслуживание пересекающихся маршрутов производится совместно. К примеру, если B тоже захочет отправлять пакеты в I, он выполнит вычисление маршрута. Но в таком случае запрос сначала достигнет узла D, который уже знает о существовании маршрута, ведущего к I. И тогда узел D может отправить B ответ, содержащий нужный маршрут, тем самым избежав лишних вычислений.

Существует множество других схем маршрутизации в произвольных сетях. Еще один известный алгоритм «по требованию» называется DSR (Dynamic Source Routing — динамическая маршрутизация от источника) ( Johnson и др., 2001). Другая стратегия, основанная на географии, используется в GPSR (Greedy Perimeter Stateless Routing — «жадный» протокол маршрутизации по периметру без учета состояний). Если все узлы знают свое географическое местоположение, доставка пакета получателю может происходить без вычисления маршрута: пакет можно каждый раз отправлять в правильном направлении, возвращаясь назад в случае, если иначе путь приведет в тупик. Выбор протокола зависит в первую очередь от характеристик данной произвольной сети.

5.3. Алгоритмы борьбы с перегрузкой

Когда количество пакетов, передаваемых одновременно по сети (или ее части), превышает некий пороговый уровень, производительность сети начинает снижаться. Такая ситуация называется перегрузкой (congestion). За борьбу с перегрузкой отвечают сетевой и транспортный уровни. Поскольку перегрузка происходит в сети, именно сетевой уровень непосредственно с ней сталкивается, и именно он должен в конечном итоге решить, что делать с лишними пакетами. Однако наиболее эффективный метод борьбы с перегрузкой — снижение нагрузки на сеть со стороны транспортного уровня. В таком случае сетевой и транспортный уровни должны работать вместе. В этой главе мы рассмотрим те аспекты перегрузки, которые относятся к сетевому уровню. Но чтобы картина была полной, мы обратимся к транспортным аспектам в главе 6.

На рис. 5.19 показано, как начинается перегрузка. Когда число пакетов, посылаемых хостами в сеть, не превышает ее пропускной способности, число доставленных пакетов пропорционально числу отправленных. Если отправить вдвое больше пакетов, вдвое больше пакетов будет и получено. Однако, когда нагрузка на сеть приближается к пропускной способности, большие объемы трафика постепенно заполняют буферы маршрутизаторов, и в результате некоторые пакеты теряются. Эти потерянные пакеты расходуют часть пропускной способности, поэтому число доставленных пакетов оказывается ниже идеальной кривой. Это означает, что сеть перегружена.

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

Если сеть устроена не идеально, в ней может произойти затор (congestion collapse), при котором производительность падает с ростом нагрузки на сеть (если нагрузка превышает пропускную способность). Это может произойти, если пакеты настолько задерживаются в сети, что в момент доставки они уже не нужны. Например, на ранних этапах работы сети Интернет время, которое пакет проводил в очереди, ожидая отправки непереданных пакетов (при скорости 56 Кбит/с), зачастую превышало то время, которое пакет мог находиться в сети. В результате его приходилось удалять. Еще один неприятный сценарий — ситуация, когда отправители повторно передают пакеты, которые сильно задерживаются, полагая, что они утеряны. В таком случае пропускная способность сети используется неэффективно, поскольку по сети передаются копии одного и того же пакета. Чтобы наглядно продемонстрировать влияние этих факторов на производительность, мы отобразили на оси у (см. рис. 5.19) полезную нагрузку (goodput), то есть скорость, с которой по сети передаются полезные пакеты.

В идеале сеть должна быть устроена так, чтобы перегрузки происходили в ней как можно реже и чтобы в случае перегрузок в ней не возникало заторов. К сожалению, перегрузок не всегда можно избежать. Если вдруг потоки пакетов начинают прибывать на маршрутизатор сразу по трем или четырем входным линиям и всем им нужна одна и та же выходная линия, то образуется очередь. Когда у маршрутизатора закончится свободная память для буферирования все прибывающих пакетов, их негде будет сохранять, и они начнут теряться. Увеличение объема памяти маршрутизаторов может в какой-то степени помочь, но Нэгл (Nagle) в 1987 году показал, что даже если у маршрутизаторов будет бесконечное количество памяти, ситуация с перегрузкой не улучшится, а, наоборот, ухудшится. Причина в том, что к тому времени, когда пакеты доберутся до начала очереди, они уже запоздают настолько, что источником будут высланы их дубликаты. В результате ситуация не улучшится, а ухудшится: в сети возникнет затор.

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

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

Чтобы разница между этими двумя проблемами стала яснее, представьте себе сеть, состоящую из оптоволоконных линий с пропускной способностью в 100 Гбит/с, по которой суперкомпьютер пытается передать большой файл персональному компьютеру, способному принимать данные со скоростью 1 Гбит/с. Хотя перегрузки сети в данной ситуации не наблюдается, алгоритм управления потоком довольно часто заставляет суперкомпьютер приостанавливать передачу, чтобы персональный компьютер мог успевать принимать файл.

А вот другой пример. Рассмотрим сеть, состоящую из 1000 больших компьютеров, соединенных линиями с пропускной способностью в 1 Мбит/с. Одна половина компьютеров пытается передавать файлы другой половине со скоростью 100 Кбит/c. Здесь проблема заключается уже не в том, что медленные получатели не успевают принимать данные, посылаемые им быстрыми отправителями, а просто в неспособности сети пропустить весь предлагаемый трафик.

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

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

5.3.1. Подходы к борьбе с перегрузкой

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

Рис. 5.20. Временные шкалы подходов к борьбе с перегрузкой

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

Чтобы максимально эффективно использовать пропускную способность сети, маршруты могут строиться в соответствии со специальными схемами трафика, которые меняются в течение суток по мере того, как пользователи просыпаются и ложатся спать в различных временных зонах. Можно, например, отвести трафик от загруженных линий, изменив весовые коэффициенты кратчайшего пути. Некоторые радиостанции используют вертолеты, чтобы получить сведения о перегрузках на дорогах и передать их радиослушателям, которые благодаря этому смогут объехать «горячие точки». Это называется маршрутизацией с учетом состояния трафика (traffic-aware routing). В таком случае полезно также разделять трафик, направляя его по разным линиям.

Но иногда увеличение пропускной способности оказывается невозможным. Тогда единственным средством борьбы с перегрузкой является снижение нагрузки. В сети виртуальных каналов новые соединения могут быть отклонены, если они приведут к перегрузке сети. Это называется управлением доступом (admission control).

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

Этот подход (регулирование трафика — traffic throttling) требует ответа на два вопроса: как обнаружить зарождающуюся перегрузку и как сообщить об этом отправителю, который должен замедлить трафик. Решить первую проблему можно, если маршрутизаторы будут следить за средней нагрузкой на сеть, временем ожидания в очереди и числом утерянных пакетов. В любом случае увеличение значений параметров сигнализирует о приближении к перегрузке.

Для решения второй проблемы необходимо, чтобы маршрутизаторы входили в петлю обратной связи с отправителями. Чтобы данная схема работала, необходимо тщательно настроить временные параметры. Если каждый раз, когда два пакета приходят одновременно, какой-нибудь нервный маршрутизатор будет кричать «Стоп!», а простояв без работы 20 мкс, он же будет давать команду «Давай!», система будет находиться в состоянии постоянных незатухающих колебаний. С другой стороны, если маршрутизатор для большей надежности станет ждать 30 минут, прежде чем что-либо сообщить, то механизм борьбы с перегрузкой будет реагировать слишком медленно, чтобы приносить вообще какую-либо пользу. Своевременная доставка сообщений обратной связи — не такая уж простая задача. Кроме того, необходимо добиться того, чтобы маршрутизаторы отправляли больше сообщений, если сеть уже перегружена.

Наконец, если все остальные методы не работают, сеть вынуждена удалить пакеты, которые она не может доставить. Для этого используется общий термин сброс нагрузки (load shedding). Если правильно выбрать удаляемые пакеты, можно предотвратить затор.

5.3.2. Маршрутизация с учетом состояния трафика

Первый подход, который мы рассмотрим, называется маршрутизацией с учетом состояния трафика. Схемы, рассмотренные нами в разделе 5.2, используют фиксированные весовые коэффициенты связей. Эти схемы могут адаптироваться к изменению топологии, но не к изменению нагрузки. Причина, по которой при вычислении маршрутов нагрузку следует принимать во внимание, состоит в том, что благодаря этому можно будет отвести поток трафика от «горячих точек», в которых в первую очередь возникает перегрузка.

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

Маршрутизация с учетом состояния трафика использовалась на ранних этапах развития сети Интернет в рамках этой модели (Khanna и Zinky, 1989). Однако здесь есть небольшая опасность. Рассмотрим сеть, изображенную на рис. 5.21. Она разделена на две части — Восток и Запад, соединенные связями CF и EI. Предположим, что основной трафик между Западом и Востоком проходит по связи CF, в результате чего эта линия оказывается слишком нагруженной, что приводит к длительным задержкам. Учет времени ожидания в очереди при вычислении кратчайшего пути сделает связь EI более популярной. После внесения изменений в таблицы маршрутизации большинство трафика пойдет по связи EI, и она окажется слишком нагруженной. Поэтому при следующем обновлении таблиц кратчайшим путем снова станет CF. В конечном итоге значения в таблицах маршрутизации будут сильно колебаться, что приведет к ошибкам при выборе маршрутов и другим проблемам.

Рис. 5.21. Сеть, в которой восточная и западная части соединены двумя связями

Если оставить в стороне нагрузку и учитывать только пропускную способность и задержку распространения, такая проблема не возникает. Попытки учесть нагрузку, используя узкий диапазон весовых значений, лишь замедляют колебания маршрутов. Удачное решение проблемы основывается на двух методах. Первый — это многопутевая маршрутизация, при которой между отправителем и получателем может существовать несколько путей. Применительно к нашему примеру это означает, что пакеты могут передаваться по обеим связям между Востоком и Западом. Второй метод состоит в следующем: схема маршрутизации должна перемещать трафик по маршрутам настолько медленно, чтобы она сходилась (так, например, работает схема Gallagher, 1977).

Из-за всех этих трудностей протоколы маршрутизации сети Интернет обычно не строят маршруты на основании нагрузки на сеть. Вместо этого перегрузки регулируются вне протокола маршрутизации за счет изменения входных данных. Это называется управлением трафиком (traffic engineering).

5.3.3. Управление доступом

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

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

Часто в качестве характеристик трафика выступают скорость и форма. Однако вопрос о том, как просто и осмысленно описать эти характеристики, достаточно трудный: трафик обычно неравномерен, и поэтому средняя скорость не является особенно показательной. Например, обеспечить поиск в Сети гораздо сложнее, чем просмотр потокового видео такого же объема, поскольку блоки трафика с большей вероятностью приводят к перегрузке маршрутизаторов сети. Этот эффект чаще всего называют дырявым ведром (leaky bucket) или маркерным ведром (token buket). Дырявое ведро использует два параметра, ограничивающих среднюю скорость и мгновенный выброс трафика. Алгоритм дырявого ведра широко используется для улучшения качества обслуживания, поэтому мы поговорим о нем более подробно в разделе 5.4.

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

Даже если сеть не берет на себя никаких обязательств, она может использовать характеристики трафика для управления доступом. В таком случае задача сводится к тому, чтобы оценить число виртуальных каналов, достаточное для обеспечения нужной пропускной способности сети и работы без перегрузок. Предположим, что все виртуальные каналы, способные передавать трафик со скоростью до 10 Мбит/с, используют один и тот же физический канал с пропускной способностью 100 Мбит/с. Сколько каналов можно использовать? Очевидно, что в случае 10 каналов нет никакого риска перегрузки, однако в нормальной ситуации это неэффективно, поскольку вряд ли все 10 каналов будут одновременно работать в полную силу. В действующих сетях для оценки числа возможных каналов используются статистические данные. Таким образом, за счет допустимого увеличения риска сеть выигрывает в производительности.

Можно совместить принципы управления доступом и маршрутизации с учетом состояния трафика, направляя маршруты в обход «горячих точек». Для примера рассмотрим сеть, показанную на рис. 5.22, в которой два маршрутизатора перегружены.

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

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

Рис. 5.22. Сеть: а — перегруженная; б — часть сети без перегрузки. Показан виртуальный канал между A и B

5.3.4. Регулирование трафика

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

Давайте рассмотрим несколько подходов к регулированию трафика, применяемых в дейтаграммных сетях и сетях виртуальных каналов. Каждый такой подход должен решать две проблемы. Во-первых, маршрутизаторы должны узнавать о перегрузке до того, как она произойдет. Для этого каждый маршрутизатор должен непрерывно отслеживать ресурсы, которые он использует. Здесь возможны три варианта: использование выходных линий, буферизация очереди пакетов данного маршрутизатора и число пакетов, утерянных вследствие неправильной буферизации. Наиболее эффективным является второй вариант. Средние показатели использования линий не отражают реальной картины при прерывистом трафике. Так, значение 50 % — это немного при сплошном трафике и слишком много при переменном трафике. Число утерянных пакетов становится известно слишком поздно: пакеты начинают теряться уже после возникновения перегрузки.

Время ожидания в очереди маршрутизатора явно отражает то, как перегрузка сказывается на пакетах. Будучи низким в большинстве случаев, этот показатель должен резко возрастать при скачке трафика, когда увеличивается число непереданных пакетов. Такую оценку времени ожидания в очереди (d) можно получить с помощью несложных вычислений, периодически замеряя мгновенную длину очереди s и рассчитывая новое значение переменной d по формуле:

d

= ad

новое

старое

+ (1

a) s,

где константа а определяет, насколько быстро маршрутизатор забывает свое прошлое. Это называется ЭВСС (экспоненциально взвешенное скользящее среднее — Exponentialy Weighted Moving Average, EWMA). Оно сглаживает различные флуктуации и работает как фильтр низких частот. Как только значение d выходит за пороговый уровень, маршрутизатор узнает о начале перегрузки.

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

Сдерживающие пакеты

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

Когда хост-отправитель получает сдерживающий пакет, он должен уменьшить трафик к указанному получателю, к примеру, на 50 %. В дейтаграммной сети выбор случайного пакета, скорее всего, приведет к тому, что сдерживающие пакеты дойдут до самых быстрых отправителей, поскольку именно их пакеты составляют большую часть очереди. Такая неявная обратная связь позволяет предотвратить перегрузку, не мешая тем отправителям, действия которых не вызывают проблем. По той же причине велика вероятность того, что множественные сдерживающие пакеты будут отправлены на нужный хост и адрес. В течение определенного промежутка времени — пока уменьшение трафика не подействует — хост будет игнорировать дополнительные пакеты. По истечении этого времени новые сдерживающие пакеты сообщат ему, что сеть все еще перегружена.

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

Явное уведомление о перегрузке

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

Этот метод называется явным уведомлением о перегрузке (ECN — Explicit

Congestion Notification) и используется в сети Интернет (Ramakrishnan, 1988). Это усовершенствованный вариант ранних протоколов уведомления о перегрузке, в частности бинарной схемы обратной связи Ramakrishnan и Jain (1988), применявшейся в архитектуре DECNET. На информацию о перегрузке в заголовке пакета отводится два бита. В момент отправки пакет не имеет метки (рис. 5.23). При проходе через перегруженный маршрутизатор пакет получает отметку о перегрузке. После этого получатель передает эти сведения отправителю, добавив явное уведомление о перегрузке в следующий ответный пакет. На рисунке этот процесс показан пунктирной линией, чтобы показать, что он происходит над IP-уровнем (например, на уровне TCP). Далее, как и в случае со сдерживающими пакетами, отправитель должен начать регулировать трафик.

Рис. 5.23. Явное уведомление о перегрузке

Обратное давление на ретрансляционных участках

При больших скоростях передачи данных или при сильной удаленности хостов много новых пакетов может быть отправлено даже после передачи уведомлений о перегрузке, поскольку реакция на уведомление занимает некоторое время. Рассмотрим, к примеру, хост в Сан-Франциско (маршрутизатор A на рис. 5.24), посылающий поток данных на хост, расположенный в Нью-Йорке (маршрутизатор D на рис. 5.24), со скоростью OC-3 155 Мбит/с. Если у нью-йоркского хоста начнет кончаться буферная память, сдерживающему пакету потребуется около 40 мс на то, чтобы добраться обратно в Сан-Франциско и сообщить о том, что необходимо снизить объем трафика. Явное уведомление о перегрузке займет еще больше времени, поскольку оно доставляется через получателя. Распространение сдерживающего пакета схематично показано на второй, третьей и четвертой диаграммах рис. 5.24, а. За те 40 мс, пока этот пакет движется по сети, в сторону нью-йоркского маршрутизатора передается еще 6,2 Мбит данных, с которыми тоже надо как-то совладать. Только к седьмой диаграмме (рис. 5.24, а) маршрутизатор заметит начавшееся снижение потока.

Однако есть альтернативный метод, позволяющий бороться с этой проблемой. Он заключается в том, что сдерживающий пакет влияет на трафик каждого маршрутизатора, через который он проходит. Это показано на последовательности диаграмм на рис. 5.24, б. Как только сдерживающий пакет достигает точки F, поток данных от F в сторону D должен быть уменьшен. Таким образом, F резервирует для соединения большее количество буферной памяти: источник все еще продолжает заваливать это направление своими данными. Нагрузка на D мгновенно спадает, как головная боль у страдальца, рекламирующего по телевизору чудодейственные пилюли. На следующем шаге сдерживающий пакет, продолжая свой путь, достигает E и приказывает уменьшить поток в сторону F. В результате в течение какого-то времени точке E приходится выдерживать повышенную нагрузку, но зато мгновенно освобождается от своего бремени точка F. Наконец, победный марш сдерживающего пакета приводит его к источнику всех бед — точке A, и теперь поток снижается на самом деле.

Рис. 5.24. Сдерживающий пакет влияет только на источник (а); Сдерживающий пакет влияет на все промежуточные участки (б)

Результатом применения метода сдерживания трафика на ретрансляционных участках является максимально быстрое устранение перегрузки в самой горячей точке за счет использования большего объема буферной памяти промежуточных маршрутизаторов. Таким образом, перегрузка пресекается без потери пакетов. Эта идея обсуждается более подробно у Mishra и др. (1996).

5.3.5. Сброс нагрузки

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

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

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

Более разумные алгоритмы сброса нагрузки требуют участия отправителей. В качестве примера можно привести пакеты, содержащие сведения о маршрутизации. Эти пакеты значительно важнее обычных пакетов с данными, поскольку они устанавливают маршруты; если они будут утеряны, может пострадать связность сети. Другой пример — алгоритмы сжатия видеосигнала (например, MPEG), которые периодически посылают полный кадр, а последующие кадры представляют собой карты изменений относительно последнего полного кадра. В таком случае потеря пакета, содержащего разностный сигнал, не так страшна, как потеря полного кадра, так как от этого полного кадра зависят последующие пакеты.

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

Конечно, при отсутствии стимула все будут помечать свои пакеты не иначе как ОЧЕНЬ ВАЖНО — НИ В КОЕМ СЛУЧАЕ НЕ ВЫБРАСЫВАТЬ. Предотвращение неоправданного использования таких отметок часто достигается за счет сетевых ресурсов и денежных средств. Например, сеть может разрешить отправителям пересылать пакеты с большей скоростью, чем указано в договоре на предоставление услуг, если пакет будет помечаться как низкоприоритетный. Такая стратегия весьма удачна, поскольку более эффективно использует свободные ресурсы, разрешая хостам пользоваться ими, пока это никому не мешает, но не закрепляя за ними этого права.

Случайное раннее обнаружение

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

Причина, по которой эта идея имеет смысл, состоит в том, что большинство интернет-хостов узнают о перегрузке не через явные уведомления. В действительности единственным достоверным сигналом о перегрузке сети служит утеря пакетов. Трудно сконструировать такой маршрутизатор, который не удалял бы пакеты при перегрузке. Реакцией транспортных протоколов наподобие TCP на утерю пакетов при перегрузке является ответное снижение трафика от источника. Обоснование такой логики состоит в том, что TCP предназначен для проводных сетей, которые по сути своей являются очень надежными, и потеря пакетов в них чаще всего сигнализирует о переполнении буфера, а не об ошибках передачи. Чтобы TCP работал эффективно, беспроводные линии связи должны справляться с ошибками передачи на канальном уровне (так, чтобы на сетевом уровне они были не видны).

Эта ситуация и используется для уменьшения перегрузок. Если заставить маршрутизаторы сознательно терять пакеты еще до того, как ситуация станет безнадежной, то останется время на то, чтобы источник мог предпринять какие-то действия. Популярный алгоритм, реализующий данную идею, называется случайным ранним обнаружением (RED — Random Early Detection) (Floyd и Jacobson, 1993). Для определения условий, при которых следует начинать терять пакеты, маршрутизаторы постоянно высчитывают скользящее среднее длин своих очередей. Когда средняя длина очереди на какой-либо связи превышает пороговое значение, эта связь объявляется перегруженной и небольшая часть пакетов удаляется случайным образом. Именно случайный выбор пакетов увеличивает вероятность того, что самые быстрые отправители обнаружат утерю пакета; этот вариант является наилучшим, поскольку маршрутизатор не знает, какой именно источник является причиной большинства проблем в дейтаграммной сети. Отправитель заметит утерю пакета без всяких уведомлений, после чего транспортный протокол замедлит работу. Таким образом, утерянный пакет несет ту же информацию, что и сдерживающий пакет, но неявно, то есть маршрутизатор обходится без отправки реального сигнала.

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

5.4. Качество обслуживания

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

Одно из наиболее простых решений для предоставления высокого качества обслуживания заключается в создании сети с пропускной способностью, позволяющей передавать любые объемы трафика. Этот метод называется избыточным обеспечением (overprovisioning). Такая сеть будет осуществлять трафик приложений без существенных потерь, а при условии хорошей схемы маршрутизации пакеты будут доставляться с низкой задержкой. Этим ограничиваются преимущества такого алгоритма с точки зрения производительности. Можно сказать, что телефонная сеть является системой с избыточным обеспечением. Довольно редко бывает, чтобы вы подняли трубку и не услышали гудка. Дело в том, что в систему заложена настолько большая пропускная способность, что превысить ее оказывается тяжело.

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

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

1.    Что приложениям нужно от сети.

2.    Как регулировать трафик, поступающий в сеть.

3.    Как зарезервировать ресурсы на маршрутизаторах, необходимые для обеспечения

производительности.

4.    Может ли сеть принять больший объем трафика.

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

5.4.1. Требования приложений

Последовательность пакетов, передающихся от источника к приемнику, называется потоком (Clark, 1988) (flow). При этом в сетях, ориентированных на соединение, поток могут составлять все пакеты соединения, а в сетях без установления соединения — все пакеты, отправленные от одного процесса к другому. Каждому потоку требуются определенные условия, которые можно охарактеризовать следующими четырьмя основными параметрами: пропускная способность, задержка, флуктуация и потери. Все вместе они формируют то, что называется качеством обслуживания (QoS Quality of Service), необходимым потоку.

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

Таблица 5.2. Строгость требований некоторых приложений к качеству обслуживания

Приложение

Пропускная

способность

(bandwidth)

Задержка

(delay)

Флуктуации

(jitter)

Потери

(loss)

Электронная почта

Низкая

Низкая

Слабая

Средняя

Передача файлов

Высокая

Низкая

Слабая

Средняя

Веб-доступ

Средняя

Средняя

Слабая

Средняя

Удаленный доступ

Низкая

Средняя

Средняя

Средняя

Аудио по заказу

Низкая

Низкая

Сильная

Низкая

Видео по заказу

Высокая

Низкая

Сильная

Низкая

Телефония

Низкая

Высокая

Сильная

Низкая

Видеоконференции

Высокая

Высокая

Сильная

Низкая

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

С задержкой дело обстоит иначе. Приложения, занимающиеся передачей файлов, включая электронную почту и видео, не чувствительны к задержкам. Даже если все пакеты будут доставляться с задержкой в несколько секунд, ничего страшного не произойдет. Однако интерактивные приложения — например, обеспечивающие веб-доступ или удаленный доступ — к задержкам более критичны. Что касается приложений, работающих в реальном масштабе времени, их требования к задержкам очень строги. Если при телефонном разговоре все слова собеседников будут приходить с большой задержкой, пользователи сочтут такую связь неприемлемой. С другой стороны, проигрывание видео- или аудиофайлов, хранящихся на сервере, допускает наличие некоторой задержки.

Колебание (то есть стандартное отклонение) времени задержки или времени прибытия пакета называется флуктуацией (jitter). Первые три приложения (см. табл. 5.2) спокойно отнесутся к неравномерной задержке доставки пакетов, а при организации удаленного доступа этот фактор имеет более важное значение, поскольку при сильных флуктуациях обновления на экране будут появляться скачками. Видео- и особенно аудиоданные исключительно чувствительны к флуктуациям. Если пользователь просматривает видео, доставляемое на его компьютер по сети, и все кадры приходят с задержкой ровно 2,000 с, все нормально. Однако если время передачи колеблется от одной до двух секунд и приложению не удается скрыть флуктуации, то результат будет просто ужасен. При прослушивании звукозаписей будут заметны флуктуации даже в несколько миллисекунд.

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

Чтобы удовлетворить требования различных приложений, сеть может предлагать разное качество обслуживания. Важный пример — технология, использующаяся в сетях ATM, которая когда-то считалась перспективной, но впоследствии оказалась на заднем плане. Сети ATM поддерживают следующее:

1.    Постоянная битовая скорость (например, телефония).

2.    Переменная битовая скорость в реальном времени (например, сжатые видеоданные

при проведении видеоконференций).

3.    Переменная битовая скорость не в реальном времени (например, просмотр фильмов по заказу).

4.    Доступная битовая скорость (например, передача файлов).

Такое разбиение по категориям может оказаться полезным и для других целей, и для других сетей. Постоянная битовая скорость — это попытка моделирования проводной сети путем предоставления фиксированной пропускной способности и фиксированной задержки. Битовая скорость может быть переменной, например, при передаче сжатого видео, когда одни кадры удается сжать в большей степени, нежели другие. Кадр, содержащий множество разноцветных деталей, сожмется, скорее всего, плохо, и на его передачу придется потратить много битов, тогда как кадр, запечатлевший белую стену, сожмется очень хорошо. Фильмы по заказу на самом деле проигрываются не в реальном времени: часто несколько секунд видеозаписи доставляется перед проигрыванием и хранится в буфере, поэтому флуктуации попросту приводят к колебаниям объема видео, которое было получено, но не воспроизведено. Приложениям типа электронной почты нужно принципиальное наличие хоть какой-нибудь битовой скорости, они не чувствительны к задержкам и флуктуациям, поэтому говорят, что этим приложениям требуется «доступная битовая скорость».

5.4.2. Формирование трафика

Прежде чем гарантировать пользователю определенное качество обслуживания, сеть должна знать примерный объем трафика. В телефонных сетях его оценить легко: обычный звонок (в несжатом формате) требует скорости 64 Кбит/с и одного 8-битного отсчета каждые 125 мкс. Однако в данных сетях трафик является неравномерным (bursty). Трафик может прибывать неравномерно по трем причинам: непостоянная скорость трафика (например, при видеоконференциях со сжатием), взаимодействие пользователя и приложения (например, просмотр новой веб-страницы) и переключение компьютера между задачами. С неравномерным трафиком работать гораздо сложнее, чем с постоянным, так как при этом может произойти переполнение буферов и, как следствие, утеря пакетов.

Формирование трафика (traffic shaping) — способ регулировки средней скорости и равномерности потока входных данных. Приложения должны иметь возможность передавать такой трафик, который им нужен (включая неравномерный); при этом необходим простой и удобный способ описания возможных схем трафика. Когда устанавливается поток, пользователь и сеть (то есть клиент и оператор связи) договариваются об определенной схеме (то есть форме) трафика для данного потока. В результате клиент сообщает интернет-провайдеру: «Мой график передачи будет выглядеть следующим образом. Сможете ли вы это обеспечить?»

Иногда такое соглашение называется соглашением об уровне обслуживания (SLA, Service Level Agreement), особенно если в нем оговариваются комплексные потоки и длительные периоды времени (например, весь трафик для данного клиента). До тех пор пока клиент выполняет свою часть условий соглашения и посылает пакеты не чаще оговоренного в договоре графика, интернет-провайдер обязуется доставлять их в определенный срок.

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

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

Алгоритмы дырявого и маркерного ведра

Нам уже знаком один способ ограничения передаваемого приложением объема данных — скользящее окно. Этот метод использует один параметр, который ограничивает данные, передаваемые в определенный момент времени, и косвенно ограничивает скорость. Теперь мы обратимся к более общим методам описания трафика и рассмотрим алгоритмы дырявого ведра и маркерного ведра. Хотя эти алгоритмы немного отличаются друг от друга, они приводят к одинаковому результату.

Представьте себе ведро с маленькой дырочкой в днище, как показано на рис. 5.25, б. Независимо от скорости, с которой вода наливается в ведро, выходной поток обладает постоянной скоростью R, когда в ведре есть вода, и нулевой скоростью, когда ведро пустое. Кроме того, когда ведро наполняется и вода занимает весь объем B, вся лишняя вода выливается через край и теряется.

Рис. 5.25. Алгоритмы дырявого и маркерного ведра: а — формирование пакетов; б — дырявое ведро; в — маркерное ведро

С помощью такого ведра можно формировать или приводить в порядок пакеты, поступающие в сеть (рис. 5.25, а). Принцип таков: каждый хост соединяется с сетью через интерфейс, содержащий дырявое ведро. Чтобы пакет можно было отправить в сеть, в ведре должно быть достаточно места для воды. Если в момент поступления пакета ведро заполнено, пакет либо помещается в очередь до тех пор, пока в ведре не освободится достаточно места, либо отвергается. Первый вариант встречается в таких случаях, когда формирование трафика производится операционной системой хоста. Второй вариант имеет место, когда проверка трафика, поступающего в сеть, осуществляется аппаратными средствами в сетевом интерфейсе интернет-провайдера. Этот метод был предложен Тернером (Turner, 1986) и называется алгоритмом дырявого ведра (leaky bucket algorithm).

То же самое можно представить себе по-другому: в виде ведра, которое в данный момент наполняется (рис. 5.25, в). Вода вытекает из крана со скоростью R, а объем ведра, как и в предыдущем случае, равен B. Чтобы отправить пакет, необходимо, чтобы из ведра можно было вылить воду, или маркеры (так обычно называют содержимое ведра), а не налить ее туда. В ведре может содержаться ограниченное число маркеров (не более B); если ведро пустое, для отправки пакета необходимо подождать, пока не появятся новые маркеры. Этот алгоритм называется алгоритмом маркерного ведра (token bucket algorithm).

Дырявое ведро и маркерное ведро ограничивают постоянную скорость потока, при этом пропуская кратковременные пики трафика (также ограниченные максимальным значением) без искусственных задержек. Чтобы снизить нагрузку на сеть, шейпер (формирователь) трафика сглаживает крупные пики. В качестве примера представьте, что компьютер может производить данные со скоростью 1000 Мбит/с (125 млн байт в секунду) и что первая связь сети также работает на этой скорости. Хост генерирует схему трафика, показанную на рис. 5.26, а. Эта схема является неравномерной. Средняя скорость составляет 200 Мбит/с, хотя хост отправляет пиковый объем трафика в 16 000 Кбайт на максимальной скорости 1000 Мбит/с (за 1/8 секунды).

Рис. 5.26. Схема: а — трафик, передаваемый хостом; б — исходящий трафик, сформированный с помощью маркерного ведра со скоростью 200 Мбит/с и емкостью 9600 Кбайт и в — 0 Кбайт; г — уровень маркерного ведра при формировании трафика со скоростью 200 Мбит/с и емкостью 16 000 Кбайт, д — 9600 Кбайт и е — 0 Кбайт

Теперь предположим, что маршрутизаторы могут принимать данные на максимальной скорости только в течение небольших промежутков времени — до тех пор, пока буфер не заполнится. Размер буфера составляет 9600 Кбайт, что меньше, чем объем пикового трафика. В течение больших промежутков времени маршрутизаторы лучше всего работают, если скорость не превышает 200 Мбит/с (так как именно эта пропускная способность указана в соглашении с клиентом). Из этого следует, что если для передачи используется эта схема, часть трафика будет удалена, так как не поместится в буферы маршрутизаторов.

Чтобы избежать такой утери пакетов, можно сформировать трафик на хосте по методу маркерного ведра. Если скорость R равна 200 Мбит/с, а емкость B равна 9600 Кбайт, трафик попадает в границы возможностей сети. Исходящий трафик такого маркерного ведра показан на рис. 5.26, б. Хост может отправлять трафик на максимальной скорости в 1000 Мбит/с в течение небольшого промежутка времени — до тех пор, пока ведро не станет пустым. Затем он должен будет снизить скорость до 200 Мбит/с и отправить оставшуюся часть трафика. Идея в том, чтобы растянуть время отправки пикового трафика (пачки пакетов), если сеть не в состоянии обработать его в один прием. Уровень маркерного ведра показан на рис. 5.26, д. Вначале ведро наполнено, но после первой порции трафика оно становится пустым. Когда уровень достигает нуля, новые пакеты могут передаваться только с такой скоростью, с которой буфер наполняется; пока ведро снова не наполнится, отправка крупных объемов трафика невозможна. Когда трафик не поступает, ведро постепенно наполняется; пока данные приходят со скоростью заполнения ведра, оно остается пустым.

Чтобы трафик был равномерным, его можно сформировать. На рис. 5.26, в показан исходящий трафик маркерного ведра со скоростью 200 Мбит/с и емкостью 0. Это крайний случай — трафик полностью выровнен. Крупные пачки не принимаются; трафик приходит с постоянной скоростью. Уровень воды в ведре, соответственно, всегда равен нулю (рис. 5.26, е). Трафик помещается в очередь хоста, и в каждый момент времени какой-то пакет ожидает отправки.

Наконец, на рис. 5.26, д показан уровень маркерного ведра со скоростью R = 200 Мбит/с и емкостью B = 16 000 Кбайт. Это самое маленькое маркерное ведро, через которое трафик проходит без изменений. Такое ведро маршрутизатор может использовать для проверки трафика, передаваемого хостом. Такое ведро можно расположить на одном из концов сети; если трафик соответствует маркерному ведру, указанному в соглашении об обслуживании, он сможет через него пройти. Если же хост будет отправлять данные слишком быстро или неравномерно, вода в маркерном ведре закончится, и сеть узнает о том, что трафик не соответствует условиям соглашения. После этого в зависимости от конфигурации сети лишние пакеты будут либо удалены, либо помечены как низкоприоритетные. А в нашем примере ведро становится пустым лишь на короткое время — после получения большого объема трафика. После этого оно восстанавливается и снова готово принять такой трафик.

Дырявое ведро и маркерное ведро просты в реализации. Давайте посмотрим на то, как работает маркерное ведро. Хотя до этого мы говорили о втекающей и вытекающей жидкости, нужно понимать, что на практике сеть имеет дело с дискретными величинами. Реализация алгоритма маркерного ведра подразумевает наличие переменной, считающей маркеры. Счетчик увеличивается на R/AT. В нашем примере счетчик будет увеличиваться на 200 Кбит за 1 мс. Каждый раз при посылке трафика счетчик уменьшается; когда его значение доходит до нуля, передача пакетов останавливается.

Если все пакеты имеют одинаковый объем, уровень ведра можно измерять в пакетах (например, 200 Мбит — это 20 пакетов по 1250 байт). Однако чаще всего используются пакеты разного размера. Тогда уровень ведра исчисляется в байтах. Если число байт в ведре не является достаточным для отправки пакета, пакет вынужден ждать, пока ситуация не изменится (что может произойти не сразу, если скорость заполнения ведра мала).

При расчете длительности максимальной выходной пачки (до тех пор, пока ведро не станет пустым) нужно учитывать, что пока ведро опорожняется, появляются новые маркеры. При длительности пачки S с, емкости маркерного ведра B байт, скорости появления маркеров R байт/с и максимальной выходной скорости M байт/с очевидно, что максимальное количество переданных байтов в пачке будет равно B + RS байт. Мы также знаем, что количество байтов, переданных в пачке с максимальной скоростью, равно MS. Таким образом,

B + RS = MS.

Решив это уравнение, получим: S = B/(M - R). При наших параметрах B = = 9600 Кбайт, M = 125 Мбайт/с и R = 25 Мбайт/с получаем длительность пачки около 94 мс.

Недостатком алгоритма маркерного ведра является то, что скорость передачи крупных пачек снижается до постоянного значения R. Часто бывает желательно уменьшить пиковую скорость, не возвращаясь при этом к постоянному значению скорости (но и не увеличивая это значение, чтобы не пропустить в сеть дополнительный трафик). Один из способов получения более гладкого трафика состоит в помещении еще одного маркерного ведра после первого. Скорость второго ведра должна быть гораздо выше скорости первого. По сути, первое ведро определяет характеристики трафика и фиксирует его скорость, иногда позволяя отправлять крупные объемы данных. Второе ведро уменьшает максимальную скорость, с которой могут передаваться такие пачки. Например, если скорость второго ведра равна 500 Мбит/с, а емкость — 0, первая пачка поступит в сеть с максимальной скоростью 500 Мбит/с. Это меньше, чем наше предыдущее значение 1000 Мбит/с.

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

5.4.3. Диспетчеризация пакетов

Возможность управления трафиком — это неплохой начальный шаг в деле обеспечения гарантированного качества обслуживания. Однако чтобы предоставить клиенту гарантии производительности, необходимо резервировать достаточное количество ресурсов. Для этого мы будем считать, что все пакеты в потоке следуют по одному и тому же пути. При распределении их случайным образом между несколькими маршрутизаторами невозможно что-либо гарантировать. Следовательно, между источником и приемником должно быть установлено нечто вроде виртуального канала, и все пакеты, принадлежащие данному потоку, должны следовать по указанному маршруту.

Алгоритмы распределения ресурсов маршрутизатора между пакетами потока и конкурирующими потоками называются алгоритмами диспетчеризации пакетов (packet scheduling algorithm). Резервироваться могут три типа ресурсов:

1.    Пропускная способность.

2.    Буферное пространство.

3.    Время центрального процессора.

Наиболее очевидно резервирование пропускной способности. Если потоку необходима скорость в 1 Мбит/с, а исходящая линия может работать со скоростью 2 Мбит/с, то направить три потока с такими параметрами по этой линии не удастся. То есть резервирование пропускной способности означает предотвращение предоставления канала большему числу абонентов, чем канал может обработать.

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

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

Алгоритмы диспетчеризации пакетов распределяют пропускную способность и другие ресурсы маршрутизатора, определяя, какие пакеты из буфера необходимо отправить по исходящей линии следующими. Простейший вариант диспетчера мы уже обсуждали, когда говорили о принципе работы маршрутизатора. Каждый маршрутизатор помещает пакеты в очередь (отдельную для каждой исходящей линии), где пакеты ждут отправки. При этом отправка пакетов происходит в том же порядке, в котором они пришли. Этот принцип называется FIFO (First-In First-Out, первым пришел — первым ушел), или FCFS (First-Come First-Serve, первым пришел — первым обслуживается).

Маршрутизаторы, работающие по принципу FIFO, при переполнении очереди обычно удаляют последние прибывшие пакеты. Поскольку только что прибывшие пакеты помещаются в конец очереди, такое поведение называется «обрубанием хвоста» (tail drop). Это настолько простой и привычный вариант, что альтернативный метод не так-то просто себе представить. Тем не менее алгоритм случайного раннего обнаружения (RED), о котором мы говорили в разделе 5.3.5, удалял новые пакеты случайным образом, когда длина очередь начинала расти. Другие алгоритмы диспетчеризации, о которых мы здесь поговорим, используют для выбора удаляемых пакетов самые разные возможности.

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

Чтобы обеспечить изоляцию потоков и предотвратить их конфликты, было разработано множество различных алгоритмов диспетчеризации пакетов (Bhatti

и Crowcroft, 2000). Одним из первых был алгоритм справедливого обслуживания (fair queueing) (Nagle, 1987). Суть его состоит в том, что маршрутизаторы организуют отдельные очереди для каждой исходящей линии, по одной для каждого потока. Как только линия освобождается, маршрутизатор начинает циклически сканировать очереди (рис. 5.27), выбирая первый пакет следующей очереди. Таким образом, если за данную исходящую линию борются n хостов, то каждый из них имеет возможность отправить свой пакет, пропустив n—1 чужих пакетов. Получается, что все потоки передают пакеты с одинаковой скоростью. Агрессивному хосту не поможет то, что в его очереди стоит больше пакетов, чем у остальных.

Рис. 5.27. Циклическое справедливое обслуживание

Однако и с этим алгоритмом связана одна проблема: предоставляемая им пропускная способность напрямую зависит от размера пакета используемого хостом: большая часть предоставляется хостам с большими пакетами и меньшая — хостам с небольшими пакетами. В книге (Demers и др., 1990) предлагается улучшенная версия, в которой циклический опрос производится с целью выхватывания не пакета, а байта. Идея заключается в вычислении виртуального времени, то есть номера цикла, после которого отправка пакета завершится. Каждый цикл выхватывает один байт из каждой очереди, содержащей пакеты для отправки. После этого пакеты отправляются в том порядке, в котором они заканчивались при опросе очередей.

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

Рис. 5.28. Работа алгоритма: а — взвешенное справедливое обслуживание; б — время окончания отправки для пакетов

Данные таблицы (рис. 5.28, б) показывают, что первые два пакета в первых двух очередях прибывают в порядке A, B, D, F. Пакет A прибывает на нулевом цикле, а его длина равна 8 байтам, поэтому отправка завершается на 8 цикле. Точно так же отправка пакета B завершается на цикле 11. Пакет D прибывает в момент отправки B. Его отправка заканчивается через 9 циклов после окончания отправки B, и в этот момент время равно 20. Аналогичным образом получается, что время завершения отправки равно 16. При условии отсутствия новых пакетов порядок окончания отправки пакетов будет таким: A, B, F, D (хотя F прибывает после D). Может случиться так, что в верхний поток поступит небольшой пакет, который закончит отправку раньше D. Но он обойдет D только в том случае, если его передача еще не началась. При справедливом обслуживании передача пакета, передаваемого в настоящий момент, не прерывается. Этот алгоритм отправляет пакеты целиком и потому является лишь приближением схемы побайтовой передачи. Но это очень хорошее приближение, поскольку в каждый момент времени передается ровно один пакет.

Проблема данного алгоритма заключается в том, что он дает всем хостам одинаковые приоритеты. Во многих случаях желательно предоставлять, например, видеосерверам большую пропускную способность, чем обычным файл-серверам, чтобы они могли посылать два или более байт за цикл. Такая модификация алгоритма называется взвешенным справедливым обслуживанием (WFQ — Weighted Fair Queueing). Если количество байт, передаваемое за цикл, считать весом потока, W, то формула вычисления времени окончания передачи будет выглядеть так:

где— время прибытия,— время окончания отправки, а— длинапакета. Нижняя очередь (рис. 5.28, а) имеет вес 2, поэтому ее пакеты передаются быстрее. Это хорошо видно, если посмотреть на значения времени окончания отправки (см. рис. 5.28, б). Еще один фактор, который необходимо учитывать, — это сложность реализации. Метод взвешенного справедливого обслуживания помещает пакеты в очередь, сортируя их по времени окончания отправки. Для N потоков это требует по меньшей мереопераций для каждого пакета, что является трудновыпол

нимым при большом количестве потоков на высокоскоростных маршрутизаторах. Существует упрощенная схема DRR (deficit round robin), работающая гораздо эффективнее — всего за 0(1) операций для каждого пакета (Shreedhar и Varghese, 1995). Она широко применяется для алгоритма взвешенного справедливого обслуживания.

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

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

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

5.4.4. Управление доступом

Теперь, когда мы познакомились с основными составляющими качества обслуживания (QoS), самое время собрать все это воедино. Гарантии качества обслуживания выполняются через управление доступом. До этого мы рассматривали управление доступом как средство борьбы с перегрузкой, что является гарантией производительности, пусть даже не очень эффективной. Здесь мы предъявляем к гарантиям более серьезные требования, но модель остается той же. Пользователь передает в сеть поток, предъявляя определенные требования к качеству обслуживания. Сеть принимает или отвергает этот поток в зависимости от своих возможностей и обязательств перед другими клиентами. Если сеть принимает поток, она должна заранее зарезервировать ресурсы, чтобы при передаче трафика по этому потоку клиент получил необходимое качество обслуживания.

Резервирование может производиться на всех маршрутизаторах, расположенных в узлах пути, по которому следуют пакеты. Если на каком-то из них ресурсы не зарезервированы, там может возникнуть затор, и гарантии качества обслуживания рискуют оказаться невыполненными. Многие алгоритмы маршрутизации выбирают наилучший путь от отправителя до получателя и направляют весь трафик по этому пути. Однако это может привести к тому, что часть потоков будут отвергнуты из-за недостатка ресурсов на узлах наилучшего пути. Тогда, чтобы выполнить свои обязательства перед клиентом, сеть выберет другой путь для отправки крупного потока. Это называется QoS-маршрутизацией (QoS routing). Описание этих методов можно найти в работе Chen и Nahrstedt (1998). Если заранее распределять трафик для одного и того же адреса по нескольким путям, найти дополнительные ресурсы будет гораздо проще. Маршрутизаторы могут выбирать пути с одинаковой стоимостью и использовать маршрутизацию, пропорциональную или эквивалентную емкостям исходящих связей. Однако существуют и более сложные алгоритмы (Nelakuditi и Zhang, 2002).

Для выбранного пути процесс принятия решения об обработке или игнорировании потока сложнее, нежели простое сравнение запрашиваемых потоком ресурсов (пропускной способности, буферной памяти, времени центрального процессора) с имеющимися. Во-первых, хотя многие приложения и знают свои требования по пропускной способности, они понятия не имеют, какой объем буферной памяти и сколько тактов работы процессора им требуется. Следовательно, нужен, по крайней мере, иной способ описания потоков и определения ресурсов, выделяемых маршрутизатором. Вскоре мы вернемся к этому вопросу.

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

Наконец, некоторые приложения могут поторговаться за параметры пакетов, а некоторые не могут. Скажем, проигрыватель видео, предоставляющий обычно 30 кадров/с, может согласиться работать на 25 кадрах/с, если для 30 не хватает пропускной способности. Аналогично можно настраивать количество пикселов на кадр, полосу пропускания для аудиоданных и другие свойства потоков различных приложений.

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

В качестве содержимого спецификации потока рассмотрим пример (табл. 5.3), базирующийся на RFC 2210 и RFC 2211 для интегрального обслуживания — технологии QoS, о которой мы поговорим в следующем разделе. В спецификации содержится пять параметров. Первые два, скорость маркерного ведра и размер маркерного ведра, позволяют вычислить максимальную скорость, которую отправитель может поддерживать в течение длительного времени, усредненную по большому временному отрезку, а также максимальный объем пачки, передаваемой за короткий промежуток времени.

Таблица 5.3. Пример спецификации потока

Параметр

Единицы измерения

Скорость маркерного ведра

байт/с

Размер маркерного ведра

байт

Пиковая скорость передачи данных

байт/с

Минимальный размер пакета

байт

Максимальный размер пакета

байт

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

Наконец, последние два параметра определяют минимальный и максимальный размеры пакетов, включая заголовки транспортного и сетевого уровней (например, TCP и IP). Минимальный размер удобен, поскольку обработка каждого пакета занимает какое-то, пусть даже очень малое время. Маршрутизатор, может быть, готов принимать 10 000 пакетов в секунду по 1 Кбайт каждый, но не готов обрабатывать 100 000 пакетов в секунду по 50 байт, несмотря на то что во втором случае скорость передачи данных меньше, чем в первом. Максимальный размер пакета не менее важен, но уже по другой причине. Дело в том, что существуют определенные внутрисетевые ограничения, которые ни в коем случае не должны быть превышены. Например, если путь потока лежит через Ethernet, то максимальный размер пакета будет ограничен 1500 байтами, независимо от того, какого размера пакеты могут поддерживать другие части сети.

Интересно, каким образом маршрутизатор преобразует спецификацию потока в набор определенных резервируемых ресурсов? На первый взгляд может показаться, что если один из каналов маршрутизатора работает со скоростью 1 Гбит/с, а средний размер пакета равен 1000 бит, он может обрабатывать 1 млн пакетов в секунду. Однако это не так, поскольку из-за статистических флуктуаций нагрузки передача будет периодически приостанавливаться на некоторое время. Если для выполнения всей работы канал должен использовать всю свою мощность, перерыв длиной в несколько секунд станет причиной завала, который ему никогда не удастся разгрести.

Однако даже если нагрузка несколько меньше теоретической емкости, все равно могут образовываться очереди и возникать задержки. Рассмотрим ситуацию, в которой пакеты прибывают нерегулярно со средней скоростью прибытия X пакетов в секунду. Пакеты имеют случайную длину и могут передаваться по каналу со средней скоростью обслуживания ц пакетов в секунду. Предположим, что как скорость прибытия, так и скорость обслуживания имеют пуассоновское распределение (такие системы называются системами массового обслуживания M/M/1, где «М» означает «марковский процесс», который в данном случае является еще и пуассоновским). Тогда, используя теорию массового обслуживания, можно доказать, что средняя задержка T, присущая пакету, равна

где— коэффициент использования центрального процессора. Первый со

множитель— это задержка при отсутствии конкуренции. Второй сомножитель представляет собой дополнительную задержку, возникающую благодаря конкурентной борьбе с другими потоками. Например, если950 000 пакетов/с, а ц = 1 000 000 пакетов/с, тогда р = 0,95 и средняя задержка каждого пакета составляет 20 мкс вместо 1 мкс. Эти подсчеты учитывают и задержку доставки, и задержку обработки: при малом трафике отношениеЕсли на пути потока стоят, скажем,

30 маршрутизаторов, то одна только задержка обслуживания составит 600 мкс.

Один из методов соотнесения характеристик потока и ресурсов маршрутизатора, необходимых для выполнения гарантий пропускной способности и времени задержки, был предложен Parekh и Gallagher (1993, 1994). Согласно этому методу, отправитель должен сформировать трафик с помощью маркерных ведер (R, B), а маршрутизаторы должны использовать взвешенное справедливое обслуживание. Каждому потоку присваивается вес W, достаточный для того, чтобы опустошить маркерное ведро со скоростью R (рис. 5.29). Если, например, скорость потока составляет 1 Мбит/с, а мощности маршрутизатора и исходящей связи равны 1 Гбит/с, вес потока должен превышать одну тысячную от общей суммы весов всех потоков этого маршрутизатора для исходящей связи. Это обеспечит потоку минимальную пропускную способность. Если поток не может получить необходимую ему скорость, он не будет допущен в сеть.

Рис. 5.29. Гарантии пропускной способности и задержки с использованием маркерных ведер и взвешенного справедливого обслуживания

Наибольшее время ожидания в очереди для данного потока является функцией максимальной емкости маркерного ведра. При равномерном трафике пакеты проходят через маршрутизатор с той же скоростью, с которой прибывают. При этом не происходит никаких задержек (не считая эффектов пакетирования). С другой стороны, если трафик передается пачками, то пачка максимального размера, B, может прибыть на маршрутизатор целиком. Тогда максимальная задержка, D, будет равна времени прохождения пакета через маршрутизатор при фиксированной пропускной способности, или B/R (опять же, не считая эффектов пакетирования). Если этот показатель слишком высокий, поток может запросить большую пропускную способность.

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

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

5.4.5. Интегральное обслуживание

В 1995-1997 годах проблемная группа проектирования сети Интернет (IETF) прилагала множество усилий по продвижению архитектуры потокового мультимедиа. В результате появилось две дюжины документов RFC, начинающихся с префикса RFC и включающих порядковые номера 2205-2212. Общее название этих трудов — потоковые алгоритмы или интегральное обслуживание (integrated services). Предлагаемая технология предназначена как для одноадресных, так и для многоадресных приложений. Примером первых может быть видеоклип на сайте новостей, доставляемый в виде потока пользователю, пожелавшему посмотреть его. Пример вторых — набор станций цифрового телевидения, осуществляющих широковещательное распространение своих программ в виде потоков IP-пакетов. Данной услугой может пользоваться большое число абонентов, расположенных в разных географических точках. Ниже мы более подробно рассмотрим многоадресную рассылку, поскольку одноадресная передача — это лишь особый случай многоадресной.

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

RSVP — протокол резервирования ресурсов

Главная составляющая архитектуры интегрального обслуживания, открытая для пользователей сети, называется протоколом резервирования ресурсов (RSVP —

Resource reSerVation Protocol). Он описывается в документах RFC 2205-2210. Как следует из названия, протокол предназначен для резервирования ресурсов; другие протоколы применяются для описания передачи данных. RSVP позволяет нескольким отправителям посылать данные нескольким группам абонентов, разрешает отдельным получателям переключать каналы и оптимизирует использование пропускной способности, в то же время устраняя возникновение перегрузки.

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

Для примера рассмотрим сеть, показанную на рис. 5.30, а. Хосты 1 и 2 являются многоадресными передатчиками, а хосты 3, 4 и 5 — многоадресными приемниками.

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

Рис. 5.30. Протокол резервирования ресурсов: а — сеть; б — связующее дерево многоадресной рассылки для хоста 1; в — связующее дерево многоадресной рассылки для хоста 2

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

Пример резервирования показан на рис. 5.31, а. Здесь хост 3 запросил канал к хосту 1. После создания канала поток пакетов от хоста 1 к хосту 3 может течь, не боясь попасть в затор. Рассмотрим, что произойдет, если теперь хост 3 зарезервирует канал к другому передатчику, хосту 2, чтобы пользователь мог одновременно смотреть две телевизионные программы. Зарезервированный второй канал показан на рис. 5.31, б. Обратите внимание: между хостом 3 и маршрутизатором E требуется наличие двух отдельных каналов, так как передаются два независимых потока.

Наконец, на рис. 5.31, в хост 5 решает посмотреть программу, передаваемую хостом 1, и также резервирует себе канал. Сначала требуемая пропускная способность резервируется до маршрутизатора H. Затем этот маршрутизатор замечает, что у него уже есть канал от хоста 1, поэтому дополнительное резервирование выше по дереву не требуется. Обратите внимание на то, что хосты 3 и 5 могут запросить различную пропускную способность (например, у хоста 3 маленький экран, поэтому ему не нужно высокое разрешение), следовательно, маршрутизатор H должен зарезервировать пропускную способность, достаточную для удовлетворения самого жадного получателя.

Рис. 5.31. Пример резервирования: а — хост 3 запрашивает канал к хосту 1; б — затем хост 3 запрашивает второй канал к хосту 2; в — хост 5 запрашивает канал к хосту 1

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

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

5.4.6. Дифференцированное обслуживание

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

По этим причинам IETF был создан упрощенный подход к повышению качества обслуживания. Его можно реализовать локально в каждом маршрутизаторе без предварительной настройки и без включения в процесс всех устройств вдоль маршрута. Подход известен как ориентированное на классы (в отличие от ориентированного на потоки) качество обслуживания. Проблемной группой IETF была стандартизована специальная архитектура под названием дифференцированное обслуживание (differentiated services), описываемая в документах RFC 2474, RFC 2475 и во многих других. Ниже мы опишем ее.

Дифференцированное обслуживание может предоставляться набором маршрутизаторов, образующих административный домен (например, интернет-провайдер или телефонную компанию). Администрация определяет множество классов обслуживания и соответствующие правила маршрутизации. Пакеты, приходящие от абонента, пользующегося дифференцированным обслуживанием, получают метку с информацией о классе. Эти сведения записываются в поле Дифференцированное обслуживание пакетов IPv4 и IPv6 (см. раздел 5.6). Классы определяют пошаговое поведение (per hop behaviors), так как они отвечают за то, что будет происходить с пакетом на маршрутизаторе, а не во всей сети. Пакетам с пошаговым поведением предоставляется улучшенное обслуживание (например, премиум-обслуживание) по сравнению с остальными пакетами (обычное обслуживание). К трафику класса могут предъявляться определенные требования, касающиеся его формы. Например, от него может потребоваться, чтобы он представлял собой «дырявое ведро» с определенной скоростью просачивания данных через «дырочку». Оператор, привыкший брать деньги за все, может взимать дополнительную плату за каждый пакет, обслуживаемый по высшему классу, либо может установить абонентскую плату за передачу N таких пакетов в месяц. Обратите внимание: здесь нет никакой предварительной настройки, резервирования ресурсов и трудоемких согласований параметров для каждого потока, как при интегральном обслуживании. Это делает дифференцированное обслуживание относительно просто реализуемым.

Обслуживание, ориентированное на классы, возникает и в других областях. Например, службы доставки посылок могут предлагать на выбор несколько уровней обслуживания: доставка на следующий день, через день или через два дня. В самолетах обычно бывают первый класс, бизнесс-класс и второй класс. То же самое касается поездов дальнего следования. Даже в парижской подземке до недавних пор были вагоны двух разных классов. Что касается нашей тематики, то классы пакетов могут отличаться друг от друга задержками, флуктуациями времени доставки, вероятностью быть проигнорированными в случае коллизии, а также другими параметрами (коих, впрочем, не больше, чем у кадров Ethernet).

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

Срочная пересылка

Выбор классов обслуживания зависит от решения оператора, однако поскольку пакеты зачастую необходимо пересылать между сетями, управляемыми разными операторами, проблемной группой IETF были определены классы обслуживания, не зависящие от сети. Простейший из них — класс срочной пересылки (expedited forwarding), с него и начнем. Он описывается документом RFC 3246.

Итак, идея, на которой построена срочная пересылка, очень проста. Существует два класса обслуживания: обычный и срочный. Ожидается, что подавляющая часть объема трафика будет использовать обычный класс обслуживания. Однако есть ограниченная доля пакетов, которые необходимо передавать в срочном порядке. Их нужно пересылать между сетями так, будто кроме них в сети больше нет вообще никаких пакетов. Тогда они получат обслуживание с низкими потерями, низкой задержкой и низкой флуктуацией — как раз то, что нужно для IP-телефонии. Графическое представление такой двухканальной системы показано на рис. 5.32. Имейте в виду, что физическая линия здесь только одна. Два логических пути — это своеобразный способ резервирования пропускной способности для разных классов обслуживания, а вовсе не протягивание второго провода для передачи данных рядом с основным.

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

Рис. 5.32. Срочные пакеты движутся по свободной от трафика сети

Конечно же, если пакет получает метку на хосте, входной маршрутизатор, скорее всего, захочет проверить, не выходит ли объем срочного трафика за установленные пределы. В сети маршрутизаторы могут использовать две очереди для каждой исходящей линии — для обычных и для срочных пакетов. Прибывший пакет ставится в очередь, соответствующую его классу обслуживания. Срочная очередь получает более высокий приоритет, чем обычная; это можно сделать, к примеру, с помощью диспетчера приоритетов. Таким образом, срочный трафик будет думать, что сеть пустынна и безжизненна, хотя на самом деле она может быть загружена чрезвычайно сильно.

Гарантированная пересылка

Более совершенная схема управления классами обслуживания называется схемой гарантированной пересылки (assured forwarding). Эта стратегия описывается в документе RFC 2597. Гарантированная пересылка подразумевает наличие четырех классов приоритетов, каждый из которых обладает своими ресурсами. Первые три класса можно назвать золотым, серебряным и бронзовым. Кроме того, определены три класса игнорирования пакетов, попавших в затор (низкий, средний и высокий). Итого получается 12 сочетаний, то есть 12 классов обслуживания.

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

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

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

Наконец пакеты проходят обработку на маршрутизаторах сети, где диспетчер определяет их классы. Чаще всего для четырех классов приоритетов используется метод взвешенного справедливого обслуживания: чем выше класс, тем выше вес. В результате высокоприоритетные пакеты получают большую часть пропускной способности, однако отправка низкоприоритетных пакетов не останавливается. К примеру, вес каждого класса приоритетов может быть вдвое больше, чем вес более низкого класса. В пределах одного класса приоритетов пакеты с высоким классом игнорирования удаляются в первую очередь. Это может понадобиться, например, при случайном раннем обнаружении (RED), о котором мы говорили в разделе 5.3.5. Случайное раннее обнаружение начнет удалять пакеты еще до того, как в буфере маршрутизатора закончится место. Пакеты с низким классом игнорирования все еще будут приниматься, а с высоким — отвергаться.

5.5. Объединение сетей

До сих пор мы неявно предполагали наличие единой однородной сети, в которой каждая машина использует одни и те же протоколы на каждом уровне. К сожалению, данное предположение слишком оптимистично. Существует множество различных сетей, включая персональные, локальные, региональные и глобальные. Мы уже говорили о сети Ethernet, кабельном Интернете, стационарных и мобильных телефонных сетях, стандартах 802.11, 802.16 и др. В этих сетях на каждом уровне широко применяются многочисленные и разнообразные протоколы. В следующих разделах будет уделено особое внимание вопросам, возникающим при объединении двух или более сетей, формирующих интерсеть (internetwork), или проще — интернет (internet)1.

Если бы все использовали одну и ту же сетевую технологию, объединить сети было бы гораздо проще. В большинстве случаев доминирующая сеть (например, Ethernet) существует. Некоторые ученые считают разнообразие типов сетей временным явлением, которое скоро перестанет иметь место, как только все, наконец, поймут, как замечательна сеть [вставьте свою любимую сеть]. Не стоит на это рассчитывать. Время показало, что такие рассуждения — всего лишь принятие желаемого за действительное. Разным типам сетей приходится сталкиваться с разными трудностями, поэтому, например, Ethernet и спутниковые сети всегда будут отличаться. К примеру, использование уже существующих систем (кабельной, телефонной сети и сети электропитания) при создании сетей передачи данных приводит к дополнительным ограничениям, которые изменяют свойства сети. Но при этом однородность должна сохраняться.

Если разные сети будут существовать всегда, то лучше бы нам вообще никогда не потребовалось их объединять. Но это крайне маловероятно. Боб Меткальф выдвинул такой принцип: ценность сети, состоящей из N узлов, пропорциональна числу соединений между узлами, или N2 (Gilder, 1993). Это значит, что большие сети всегда ценнее маленьких, и поэтому объединение сетей всегда будет иметь смысл.

Главный пример такого объединения — Интернет. Целью объединения всех этих сетей является предоставление пользователям возможности общаться с пользователями любой другой из этих сетей. Стоимость оплаты интернет-услуг часто зависит от доступной пропускной способности. Но на самом деле вы платите за возможность обмена пакетами с другими хостами, также подключенными к Интернету. Интернет не был бы так популярен, если бы пакеты можно было отправлять только хостам, находящимся в том же городе.

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

5.5.1. Различия сетей

Сети могут отличаться друг от друга довольно сильно и по разным параметрам. Некоторые из параметров, такие как методы модуляции или форматы кадров, нас сейчас не интересуют, поскольку они относятся к физическому и канальному уровням. В таблице 5.4 приведен список некоторых параметров, которые могут встретиться на сетевом уровне. Именно сглаживание этих различий делает обеспечение работы объединенной сети значительно более сложным делом, чем обеспечение работы одной сети.

Когда пакетам приходится пересекать несколько сетей, может возникнуть много проблем, связанных с интерфейсами между сетями. Во-первых, должна существовать возможность пересылки пакета от отправителя получателю. Что делать, если отправитель находится в сети Ethernet, а получатель — в сети WiMAX? Даже если мы можем задать адрес назначения WiMAX в сети Ethernet, пакеты нужно будет переправить из сети, не требующей соединения, в сеть, ориентированную на соединение. Тогда может понадобиться срочно создать новое соединение, что приведет к задержке и неэффективному использованию ресурсов, так как это соединение не будет активно использоваться.

Существует еще много различий, к которым необходимо приспособиться. Как, например, передать пакет группе, некоторые члены которой находятся в сети, не поддерживающей многоадресную рассылку? Различия в максимальном размере пакетов в разных сетях также составляют большую головную боль. Как передать 8000-байтовый пакет по сети, в которой максимальный размер пакета равен 1500 байтам? Когда пакеты из ориентированной на соединение сети должны пересечь не требующую соединений сеть, их порядок может нарушиться. Для отправителя это может оказаться (неприятной) неожиданностью — впрочем, как и для получателя.

Таблица 5.4. Некоторые аспекты отличия сетей

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

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

5.5.2. Способы объединения сетей

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

Уже давно идею создания общего слоя, сглаживающего различия существующих на данный момент сетей, выдвинули Серф и Кан (1974). Этот подход имел невероятный успех и нашел свое применение в протоколах IP и TCP. Сейчас, почти сорок лет спустя, IP составляет основу современной сети Интернет. За это достижение в 2004 году Серф и Кан были удостоены премии Тьюринга, которую неофициально называют Нобелевской премией в области информатики. IP использует универсальный формат пакетов, который распознается всеми маршрутизаторами и может быть передан по практически любой сети. Действие IP распространяется также и на телефонные сети. Кроме того, сейчас IP работает в сенсорных сетях и на малых устройствах, хотя раньше считалось, что такая поддержка невозможна из-за ограничений на ресурсы.

Мы уже говорили о нескольких типах устройств для соединения сетей. Среди них повторители, концентраторы, мосты, коммутаторы и шлюзы. Повторители и концентраторы просто переносят биты с одного кабеля на другой. Чаще всего это аналоговые устройства, ничего не смыслящие в протоколах вышележащих уровней. Мосты и коммутаторы работают на канальном уровне. Они могут использоваться для построения сетей, осуществляя по ходу дела минимальные преобразования протоколов, например, между сетями Ethernet со скоростями 10, 100 и 1000 Мбит/с. В этом разделе в центре нашего внимания будут устройства сетевого взаимодействия, работающие на сетевом уровне, то есть маршрутизаторы. Шлюзы, являющиеся высокоуровневыми интеркоммуникационными устройствами, будут рассмотрены позднее.

Давайте для начала посмотрим, как взаимодействие через общий сетевой слой может использоваться для объединения разнородных сетей. На рис. 5.34, а изображена интерсеть, состоящая из сетей 802.11, MPLS и Ethernet. Пусть источник в сети 802.11 хочет отправить пакет приемнику в сети Ethernet. Так как технологии отправки в этих сетях различны, и вдобавок пакету придется пройти через сеть другого типа (MPLS), на границах сетей пакеты должны быть дополнительно обработаны.

Рис. 5.34. Взаимодействие через сетевой слой: а — пакет проходит через разные сети; б — выполнение протоколов на сетевом и канальном уровне

Поскольку обычно разные сети используют разные способы адресации, пакет содержит адрес сетевого слоя, который может идентифицировать любой хост любой из трех сетей. Сначала пакет приходит на границу сетей 802.11 и MPLS. Сеть 802.11 не требует соединения, а MPLS, наоборот, ориентирована на соединение. Это значит, что необходимо создать виртуальный канал. Когда пакет пройдет по этому каналу, он достигнет границы сети Ethernet. На этом этапе пакет может оказаться слишком большим, так как 802.11 работает с кадрами большего размера, чем Ethernet. В таком случае пакет разделяется на фрагменты, каждый из которых отправляется по отдельности. Фрагменты снова собираются вместе по прибытии на адрес назначения. Так заканчивается путешествие пакета.

Выполнение протоколов для этого путешествия показано на рис. 5.34, б. Отправитель получает данные от транспортного уровня и создает пакет с заголовком общего сетевого уровня — в данном случае IP. Этот заголовок содержит адрес конечного пункта назначения, который определяет, что пакет должен быть отправлен через первый маршрутизатор. Пакет вставляется в кадр 802.11 с адресом первого маршрутизатора, после чего он передается. На маршрутизаторе из его поля данных извлекается пакет. Далее маршрутизатором анализируется содержащийся в пакете IP-адрес. Этот адрес нужно отыскать в таблице маршрутизации. В соответствии с ним принимается решение об отправке пакета на второй маршрутизатор. Чтобы пакет прошел эту часть пути, нужно добавить виртуальный канал MPLS, ведущий ко второму маршрутизатору, а пакет должен быть упакован в кадр с заголовками MPLS. На противоположном конце заголовок MPLS удаляется, а на основании адреса определяется следующий транзитный участок сетевого уровня. Этот участок ведет к конечному адресу назначения. Так как пакет является слишком длинным для сети Ethernet, он разделяется на две части, каждая из которых помещается в поле данных кадра Ethernet и передается на адрес назначения. Там заголовки кадров считываются, и содержимое исходного пакета восстанавливается. Пакет достиг пункта назначения. Следует отметить, что между случаем коммутации (установки моста) и маршрутизации есть существенная разница. При применении маршрутизатора пакет извлекается из кадра, и для принятия решения используется адрес, содержащийся именно в пакете. Коммутатор (мост) пересылает весь пакет, обосновывая свое решение значением MAC-адреса. Коммутаторы не обязаны вникать в подробности устройства протокола сетевого уровня, с помощью которого производится коммутация. А маршрутизаторы — обязаны.

К сожалению, объединение сетей — не такая простая задача, как может показаться. Когда были внедрены мосты, предполагалось, что они будут соединять разные типы сетей или, по крайней мере, разные типы локальных сетей, преобразовывая кадры одной ЛВС в кадры другой. Однако на практике это не работает. Причина проста: невозможно справиться с отличиями в свойствах ЛВС, такими как максимальный размер пакета и наличие/отсутствие классов приоритетов. Поэтому сейчас мосты используются в основном для объединения сетей одного типа на канальном уровне; для объединения разных сетей на сетевом уровне используются маршрутизаторы.

Объединение сетей нашло свое применение в построении крупных сетей. Однако условием являлось наличие общего сетевого уровня. За многие годы существования компьютерных сетей появилось множество различных протоколов. Заставить всех согласиться применять только один формат практически невозможно, особенно учитывая тот факт, что каждая компания считает самым большим своим достижением изобретение, внедрение и раскручивание собственного формата. Помимо IP, который на данный момент является практически универсальным сетевым протоколом, существуют IPX, SNA и AppleTalk. Ни один из этих протоколов не используется повсеместно. Новые протоколы будут появляться всегда. Наиболее подходящий пример сейчас — протоколы IPv4 и IPv6. Притом что оба они являются версиями IP, они не совместимы (иначе не было бы необходимости в разработке IPv6).

Маршрутизатор, поддерживающий несколько протоколов, называется мультипротокольным маршрутизатором (multiprotocol router). Он должен либо преобразовывать протоколы, либо обеспечивать соединение на уровне протокола более высокого уровня. Ни один из двух вариантов не отвечает всем требованиям сети. Соединение на более высоком уровне, например с использованием TCP, предполагает, что TCP должен быть реализован во всех сетях (что далеко не всегда так). Более того, в таком случае сетью могут пользоваться только приложения, использующие TCP (к которым не относятся многие программы, работающие в реальном времени).

Альтернативный вариант — преобразование протоколов различных сетей. Однако если форматы пакетов не являются близкими родственниками с одинаковыми информационными полями, такое преобразование всегда будет неполным и часто обречено на ошибку. К примеру, длина IPv6-адресов составляет 128 бит. И как бы ни старался маршрутизатор, такой адрес ни за что не поместится в 32-битное поле адреса IPv4. Проблема использования IPv4 и IPv6 в одной сети оказалась серьезным препятствием к внедрению IPv6. (И честно говоря, по этой же причине потребителей так и не удалось убедить в том, что они должны использовать именно IPv6.) Но еще более серьезные проблемы возникают, если требуется выполнять преобразования между принципиально разными протоколами — например, между ориентированным на соединение протоколом и протоколом, не требующим соединения. Поэтому такие преобразования практически никогда не выполняются. Пожалуй, и IP выигрывает только за счет того, что служит чем-то вроде наименьшего общего делителя. Он требует немногого от сетей, однако предоставляет только наилучший уровень обслуживания из возможных.

5.5.3. Туннелирование

Объединение сетей в общем случае является исключительно сложной задачей. Однако есть частный случай, реализация которого вполне осуществима даже для разных сетевых протоколов. Это случай, при котором хост-источник и хост-приемник находятся в сетях одного типа, но между ними находится сеть другого типа. Например, представьте себе международный банк, у которого имеется одна сеть IPv6 в Париже и такая же сеть в Лондоне, а между ними находится IPv4, как показано на рис. 5.35.

Метод решения данной проблемы называется туннелированием (tunneling). Чтобы послать IP-пакет хосту в Лондоне, хост в Париже формирует пакет, содержащий лондонский IPv6-адрес и отправляет его на мультипротокольный маршрутизатор, соединяющий парижскую сеть IPv6 и сеть IPv4. Получив пакет IPv6, маршрутизатор помещает его в другой пакет с IPv4-адресом маршрутизатора, соединяющего сеть IPv4 и лондонскую сеть IPv6. Когда пакет попадает на этот адрес, лондонский многопротокольный маршрутизатор извлекает исходный IPv6-пакет и посылает его дальше на хост назначения.

Рис. 5.35. Туннелирование пакета из Парижа в Лондон

Путь через сеть IPv4 можно рассматривать как большой туннель, простирающийся от одного многопротокольного маршрутизатора до другого. IPv6-пакет, помещенный в красивую упаковку, просто перемещается от одного конца туннеля до другого. Ему не нужно беспокоиться о взаимодействии с сетью IPv4. Это же касается и хостов Парижа и Лондона. Переупаковкой пакета и переадресацией занимаются многопротокольные маршрутизаторы. Для этого им нужно уметь разбираться в IPv6- и IPv4-пакетах. В результате весь путь от одного многопротокольного маршрутизатора до другого работает как один транзитный участок.

Чтобы сделать этот пример еще проще и понятнее, рассмотрим в качестве аналогии водителя автомобиля, направляющегося из Парижа в Лондон. По территории Франции автомобиль двигается по дороге сам. Но, достигнув Ла-Манша, он погружается в высокоскоростной поезд и транспортируется под проливом по туннелю (автомобилям не разрешается передвигаться по туннелю самим). Таким образом, автомобиль перевозится как груз (рис. 5.36). На другом конце туннеля автомобиль спускается с железнодорожной платформы на английское шоссе и снова продолжает путь своими силами. Точно такой же принцип применяется при туннелировании пакетов при прохождении через чужеродную сеть.

Рис. 5.36. Туннелирование автомобиля из Парижа в Лондон

Туннелирование широко используется для соединения изолированных хостов и сетей через сеть-посредник. В результате появляется новая сеть, которая как бы накладывается на старую. Такая сеть называется оверлейной сетью (overlay). Использование сетевого протокола с новым свойством (как в нашем примере, где сети IPv6 соединяются через IPv4) — достаточно распространенная причина. Недостатком туннелирования является то, что пакет не может быть доставлен ни на один из хостов, расположенных в сети-посреднике. Однако этот недостаток становится преимуществом в сетях VPN (Virtual Private Network виртуальная частная сеть).

VPN — обычная оверлейная сеть, использующаяся в качестве меры безопасности. Более подробно о VPN мы поговорим в главе 8.

5.5.4. Маршрутизация в объединенных сетях

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

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

Более того, оператор может не предоставлять другим операторам доступ к сведениям о весах и путях в своей сети, потому что в них может содержаться секретная информация (например, стоимость), важная в конкурентной борьбе.

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

Таким образом, нам необходим двухуровневый алгоритм маршрутизации. В пределах каждой сети для маршрутизации используется внутридоменный (intradomain) или внутренний шлюзовый протокол (interior gateway protocol; термин «шлюз» употреблялся раньше вместо термина «маршрутизатор»). Это может быть обычный протокол, учитывающий состояние линий. Между сетями применяется междоменный (interdomain) или внешний шлюзовый протокол (exterior gateway protocol). Сети могут использовать разные внутридоменые протоколы, но междоменный протокол обязан быть общим. В сети Интернет междоменный протокол называется BGP (Border Gateway Protocol пограничный межсетевой протокол). О нем мы поговорим в следующем разделе.

Здесь следует рассказать еще об одном важном понятии. Так как все сети управляются независимо, они часто называются АС автономными системами (AS — Autonomous System). Хорошая умозрительная модель АС — сеть ISP. На практике сеть ISP может состоять из нескольких АС, если они управляются независимо. Но разница не очень существенна.

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

До сих пор мы практически ничего не рассказали о том, как вычисляются маршруты в интерсети. В Интернете определяющим фактором является сотрудничество между сетями ISP. Каждая сеть может назначить цену за трафик другой сети. Еще один фактор заключается в том, что если маршрутизация в объединенных сетях требует пересечения границ государств, в игру могут неожиданно вступить законы этих государств. Так, в Швеции персональные данные граждан находятся под строжайшей защитой. Все эти внешние факторы объединяются в понятие политики маршрутизации (routing policy). В соответствии с ней автономные сети выбирают маршруты. К этому понятию мы еще вернемся, когда будем говорить о BGP.

5.5.5. Фрагментация пакетов

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

1.    Аппаратные (например, размер кадра Ethernet).

2.    Операционная система (например, все буферы имеют размер 512 байт).

3.    Протоколы (например, количество бит в поле длины пакета).

4.    Соответствие какому-либо международному или национальному стандарту.

5.    Желание снизить количество пакетов, пересылаемых повторно из-за ошибок передачи.

6.    Желание предотвратить ситуацию, когда один пакет слишком долгое время занимает канал.

Результатом действия всех этих факторов является то, что разработчики не могут выбирать максимальный размер пакета по своему усмотрению. Максимальный размер поля полезной нагрузки составляет 1500 байт для сети Ethernet и 2272 байта для

802.11. Протокол IP более щедр: размер пакета может достигать 65 515 байт.

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

Одно из решений состоит в предотвращении возникновения самой проблемы. Но сказать это проще, чем сделать. Обычно отправитель не знает, по какому пути пойдет пакет, и поэтому он также не может знать, какого размера должен быть пакет, чтобы он добрался до места назначения. Такой размер пакета называется путевым значением MTU (Path Maximum Transmission Unit максимальный размер пакета для выбранного пути). Не важно, знает ли отправитель путевое значение MTU. В сети, не требующей соединения (такой как Интернет), маршруты пакетов в любом случае выбираются независимо. Это значит, что путь может неожиданно измениться, а тогда изменится и путевое значение MTU.

Альтернативное решение проблемы заключается в разрешении шлюзам разбивать пакеты на фрагменты (fragments) и посылать каждый фрагмент в виде отдельного пакета сетевого уровня. Однако, как вам скажет любой родитель маленького ребенка, преобразование большого объекта в небольшие фрагменты существенно проще, чем обратный процесс. (Физики даже дали этому эффекту специальное название: второй закон термодинамики.) В сетях с коммутацией пакетов также существует проблема с восстановлением пакетов из фрагментов.

Рис. 5.37. Фрагментация: а — прозрачная; б — непрозрачная

Для восстановления исходных пакетов из фрагментов применяются две противоположные стратегии. Первая стратегия заключается в том, чтобы фрагментация пакета, вызванная сетью с пакетами малых размеров, оставалась прозрачной для обоих хостов, обменивающихся этим пакетом. Этот вариант показан на рис. 5.37, а. Когда на G1 приходит пакет слишком большого размера, он разбивается на фрагменты. Каждый фрагмент адресуется одному и тому же выходному маршрутизатору, G2, восстанавливающему из этих фрагментов исходный пакет. Таким образом, прохождение данных через сеть с небольшим размером пакетов оказывается прозрачным. Соседние сети даже не догадываются о том, что у них под боком пакеты страшным образом нарезаются, а потом снова склеиваются. Прозрачная фрагментация проста, но тем не менее создает некоторые проблемы. Во-первых, выходной маршрутизатор должен уметь определять момент получения последней части пакета, поэтому каждый фрагмент должен содержать либо поле счетчика, либо признак конца пакета. Кроме того, тот факт, что для последующего восстановления пакета все фрагменты должны выходить через один и тот же маршрутизатор, ограничивает возможности маршрутизации. Таким образом, налагается запрет на использование фрагментами различных путей к окончательному получателю, и в результате может оказаться потерянной часть производительности. Но еще более важным является вопрос о том, какую работу должен будет выполнить при этом маршрутизатор. Возможно, ему потребуется помесить в буфер все прибывшие фрагменты и понять, в какой момент их можно выбросить, если какие-то фрагменты не дошли. Наконец, процессы фрагментации и последующей сборки пакетов при прохождении каждой сети с малым размером пакетов приводят к дополнительным накладным расходам. Другая стратегия фрагментации состоит в отказе от восстановления пакета из фрагментов на промежуточных маршрутизаторах. Как только пакет оказывается разбитым на отдельные фрагменты, с каждым фрагментом обращаются как с отдельным пакетом. Все фрагменты проходят через маршрутизаторы, как показано на рис. 5.37, б. Задача восстановления оригинального пакета возложена на получающий хост.

Основное преимущество непрозрачной фрагментации состоит в том, что маршрутизаторы выполняют меньше работы. Так работает IP. При этом фрагменты пакета должны нумероваться таким образом, чтобы можно было восстановить исходный поток данных. В случае IP каждому фрагменту сообщается номер пакета (который есть у каждого пакета), абсолютное смещение внутри пакета (в байтах) и флажок, показывающий, является ли этот фрагмент последним в пакете. Пример такой фрагментации показан на рис. 5.38. Хотя схема очень проста, она обладает рядом важных преимуществ. По прибытии в место назначения фрагменты можно помещать в буфер в любом порядке. Кроме того, при пересечении сети с меньшим значением MTU фрагменты могут быть разделены на более мелкие фрагменты. Такая ситуация показана на рис. 5.38, в. При повторной передаче (если все фрагменты не дошли до адресата) пакет может быть разбит на фрагменты по-другому. И наконец, размер фрагментов может быть произвольным, вплоть до одного байта плюс заголовок. В любом случае пакет будет восстановлен: номер пакета и смещение помогут расположить данные в правильном прядке, а флажок укажет на конец пакета.

Рис. 5.38. Фрагментация при элементарном размере 1 байт: а — исходный пакет, содержащий 10 байт данных; б — фрагменты после прохождения через сеть с максимальным размером 8 байт; в — фрагменты после прохождения через шлюз размера 5

К сожалению, у этой схемы есть некоторые недостатки. Во-первых, это может быть более затратным, чем прозрачная фрагментация, так как заголовки фрагментов иногда передаются по связям, где без них можно обойтись. Однако настоящая проблема заключается в самом существовании фрагментов. Kent и Mogul (1987) считают, что фрагментация работает в ущерб производительности, так как при утере одного фрагмента теряется весь пакет (не говоря уже затратах на заголовки). Для хостов фрагментация оказалась тяжелым бременем, чем предполагалось вначале.

Таким образом, следует вернуться к первоначальной идее и полностью избавиться от фрагментации в сети — стратегия, использующаяся в современном Интернете. Этот процесс называется Path MTU discovery (поиск путевого значения MTU) (Mogul и Deering, 1990). Он работает так. При отправке каждого IP-пакета в его заголовок помещается информация о том, что фрагментация не разрешена. Если маршрутизатор получает слишком большой пакет, он отправляет источнику сообщение об ошибке и удаляет его (рис. 5.39). Используя информацию, содержащуюся в сообщении об ошибке, источник перераспределяет данные так, чтобы пакеты смогли пройти через маршрутизатор. Если такая же проблема возникнет на каком-то из следующих маршрутизаторов, ситуация повторится.

Рис. 5.39. Поиск путевого значения MTU

Преимущество Path MTU discovery состоит в том, что в результате источник знает необходимый размер пакета. При изменении маршрута новое путевое значение MTU станет известно источнику из новых сообщений об ошибке. Однако фрагментация между отправителем и получателем будет все равно необходима, если только путевое значение MTU не будет вычислено на более высоком уровне и передано IP. Чтобы это было возможно, TCP и IP обычно используются вместе (в виде TCP/IP). И хотя для некоторых протоколов это пока не реализовано, фрагментация все же была перенесена из сети на хосты.

Недостатком технологии Path MTU discovery является то, что отправка пакета может вызвать дополнительную задержку. Эта задержка может увеличиться в несколько раз в зависимости от того, сколько раз отправителю придется повторять отправку (меняя размер пакета), прежде чем пакет достигнет места назначения. Следовательно, возникает вопрос: существуют ли более эффективные схемы? Вероятно, да. Рассмотрим, к примеру, вариант, при котором слишком большие пакеты просто обрезаются. В таком случае получатель узнает путевое значение MTU настолько быстро, насколько это вообще возможно (по размеру полученного пакета), а также получает некоторую часть данных.

5.6. Сетевой уровень в Интернете

Теперь самое время подробно поговорить о сетевом уровне в Интернете. Но прежде чем перейти к деталям, неплохо было бы познакомиться с принципами, которые были основополагающими в прошлом, при его разработке, и которые обеспечили сегодняшний успех. В наше время люди все чаще пренебрегают ими. Между тем, эти принципы пронумерованы и включены в документ RFC 1958, с которым полезно ознакомиться (а для разработчиков протоколов он должен быть просто обязательным для прочтения, с экзаменом в конце). Этот документ использует идеи, которые были изложены в книгах (Clark, 1988; Saltzer и др., 1984). Ниже мы приведем 10 основных принципов, начиная с самых главных.

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

2.    Упрощайте. Если есть сомнения, всегда самый простой выбор является самым лучшим. Уильям Оккам (William Occam) декларировал этот принцип еще в XIV веке («Бритва Оккама»). Его можно выразить следующим образом: Борись с излишествами. Если какое-то свойство не является абсолютно необходимым, забудьте про него, особенно если такого же эффекта можно добиться комбинированием уже имеющихся свойств.

3.    Всегда делайте четкий выбор. Если есть несколько способов реализации одного и того же, необходимо выбрать один из них. Увеличение количества способов — это порочный путь. В стандартах часто можно встретить несколько опций, режимов или параметров. Почему так получается? Лишь потому, что при разработке было несколько авторитетных мнений на тему того, что является наилучшим. Разработчики должны избегать этого и сопротивляться подобным тенденциям. Надо просто уметь говорить «Нет».

4.    Используйте модульный принцип. Этот принцип напрямую приводит к идее стеков протоколов, каждый из которых работает на одном из независимых уровней. Таким образом, если обстоятельства складываются так, что необходимо изменить один из модулей или уровней, то это не затрагивает других частей системы.

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

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

7.    Проект должен быть хорошим, но он не может быть идеальным. Очень часто разработчики создают хорошие проекты, но не могут предусмотреть какие-нибудь

причудливые частные случаи. Не стоит портить то, что сделано хорошо и работает в большинстве случаев. Вместо этого имеет смысл переложить все бремя ответственности за «улучшения» проекта на тех, кто предъявляет свои странные требования.

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

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

10. Помните о производительности и цене. Никого не заинтересует сеть низкопроизводительная или дорогостоящая.

Теперь перейдем от общих принципов к деталям построения сетевого уровня Интернета. На сетевом уровне Интернет можно рассматривать как набор сетей или автономных систем (АС), соединенных друг с другом. Структуры как таковой Интернет не имеет, но все же есть несколько магистралей. Они собраны из высокопроизводительных линий и быстрых маршрутизаторов. Самые крупные магистрали (к которым необходимо присоединиться, чтобы получить доступ к остальной части сети Интернет) называются сетями Tier 1. К магистралям присоединены интернет-провайдеры, обеспечивающие доступ к Интернету домам и предприятиям, центры обработки данных и станции колокации с большим числом серверов, а также региональные сети (сети среднего уровня). Центры обработки данных обрабатывают большинство данных, передаваемых по сети Интернет. К региональным сетям присоединяются другие интернет-провайдеры, локальные сети многочисленных университетов и компаний, а также прочие периферийные сети. Схема этой квазииерархической структуры показана на рис. 5.40.

Вся эта конструкция «склеивается» благодаря протоколу сетевого уровня, IP (Internet Protocol протокол сети Интернет). В отличие от большинства ранних протоколов сетевого уровня, IP с самого начала разрабатывался как протокол межсетевого обмена. Вот как можно описать данный протокол сетевого уровня: его работа заключается в приложении максимума усилий (тем не менее без всяких гарантий) по транспортировке дейтаграмм от отправителя к получателю, независимо от того, находятся эти машины в одной и той же сети или нет.

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

В примере на рис. 5.40 пакет, посланный одним из хостов домашней сети, пересечет на своем пути четыре сети и пройдет через множество IP-маршрутизаторов, прежде чем доберется до сети предприятия, в которой расположен хост-получатель. На практике такие ситуации встречаются довольно часто, причем существуют и более длинные пути. С точки зрения связности сеть Интернет является избыточной: между магистралями и интернет-провайдерами обычно существует несколько точек соединения. Отсюда и множественные пути между хостами. Задача протокола IP — решить, какие из этих путей лучше использовать.

Рис. 5.40. Интернет представляет собой набор соединенных друг с другом сетей

5.6.1. Протокол IP версии 4

Начнем изучение сетевого уровня Интернета с формата IPv4-дейтаграмм. IPv4-дейтаграмма состоит из заголовка и основной или полезной части. Заголовок содержит обязательную 20-байтную часть, а также необязательную часть переменной длины. Формат заголовка показан на рис. 5.41. Биты передаются слева направо и сверху вниз, то есть старший бит поля Версия передается первым. (Такой порядок байтов называется «big-endian» — «со старшего конца слова». На компьютерах с порядком байтов «little-endian» — «с младшего конца слова», таких как Intel x86, требуется программное преобразование, как при передаче, так и при приеме.) Сейчас уже совершенно ясно, что для IP лучше было использовать порядок «little-endian», но на момент создания протокола это не было столь очевидным.

Поле Версия содержит версию протокола, к которому принадлежит дейтаграмма. Сейчас в сети Интернет доминирует версия 4, поэтому с нее мы и начали обсуждение IP. Включение версии в начало каждой дейтаграммы позволяет использовать

разные версии протокола в течение долгого времени. Вообще-то протокол IPv6, следующая версия IP, был разработан более десяти лет назад, но применять его начинают только сейчас. О нем мы поговорим позже в этом разделе. Широкое распространение протокол IPv6 получит тогда, когда у каждого из 231 жителей Китая будет настольный ПК, ноутбук и IP-телефон. Что касается нумерации, то ничего странного в ней нет, просто в свое время существовал мало кому известный экспериментальный протокол реального масштаба времени IPv5.

Рис. 5.41. Заголовок IP-дейтаграммы IPv4

Длина заголовка является переменной величиной, для хранения которой выделено поле IHL (в нем указано число 32-разрядных слов). Минимальное значение длины (при отсутствии необязательного поля) равно 5. Максимальное значение этого 4-битового поля равно 15, что соответствует заголовку длиной 60 байт; таким образом, максимальный размер необязательного поля равен 40 байтам. Для некоторых приложений, например для записи маршрута, по которому должен быть переслан пакет, 40 байт слишком мало. В данном случае дополнительное поле оказывается бесполезным.

Поле Дифференцированное обслуживание — одно из немногих полей, смысл которых с годами слегка изменился. Изначально это поле называлось Тип службы. Оно было (впрочем, и до сих пор) предназначено для различения классов обслуживания. Возможны разные комбинации надежности и скорости. Для оцифрованного голоса скорость доставки важнее точности. При передаче файла, наоборот, передача без ошибок важнее быстрой доставки. В поле Тип службы 3 бита использовались для задания приоритета, еще 3 бита показывали, что беспокоит хост больше всего: задержка, пропускная способность или надежность. Но поскольку никто не знал, что делать со всеми этими битами, они не использовались в течение многих лет. Когда появилось дифференцированное обслуживание, IETF сдалась и нашла этому полю другое применение. В результате первые 6 бит задают класс обслуживания; о срочном и гарантированном обслуживании мы уже говорили ранее в этой главе. В последние два бита помещаются явные уведомления о перегрузке; о таких уведомлениях шла речь в разделе, посвященном борьбе с перегрузкой.

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

Поле Идентификатор позволяет хосту-получателю определить, какому пакету принадлежат полученные им фрагменты. Все фрагменты одного пакета содержат одно и то же значение идентификатора.

Следом идет один неиспользуемый бит, что достаточно странно, так как место в IP-заголовке принято использовать экономно. В качестве первоапрельской шутки Белловин (2003) предложил использовать его для обнаружения вредоносного трафика. Тогда обеспечить безопасность сети было бы гораздо проще: пакеты с таким «злым» битом можно было бы просто удалять, зная, что они отправлены злоумышленниками. К сожалению, безопасность не так проста.

Далее следуют два однобитных поля, относящиеся к фрагментации. Бит DF означает Don’t Fragment (Не фрагментировать). Это команда маршрутизатору, запрещающая ему фрагментировать пакет. Изначально предполагалось, что это поле будет помогать хостам, которые не могут восстановить пакет из фрагментов. Сейчас оно используется при определении путевого значения MTU, которое равно максимальному размеру пакета, передаваемого по пути без фрагментации. Пометив дейтаграмму битом DF, отправитель гарантирует, что либо дейтаграмма дойдет единым блоком, либо отправитель получит сообщение об ошибке.

Бит MF означает More Fragments (Продолжение следует). Он устанавливается во всех фрагментах, кроме последнего. По этому биту получатель узнает о прибытии последнего фрагмента дейтаграммы.

Поле Смещение фрагмента указывает положение фрагмента в исходном пакете. Длина всех фрагментов в байтах, кроме длины последнего фрагмента, должна быть кратна 8. Так как на это поле выделено 13 бит, максимальное количество фрагментов в дейтаграмме равно 8192, что дает максимальную длину пакета вплоть до пределов поля Полная длина. Поля Идентификатор, MFи Смещение фрагмента используются при реализации схемы фрагментации, описанной в разделе 5.5.5.

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

Собрав пакет из фрагментов, сетевой уровень должен решить, что с ним делать. Поле Протокол сообщит ему, какому процессу транспортного уровня передать этот пакет. Это может быть TCP, UDP или что-нибудь еще. Нумерация процессов глобально стандартизирована по всему Интернету. Номера протоколов вместе с некоторыми другими были сведены в RFC 1700, однако теперь доступна интернет-версия в виде базы данных, расположенной по адресу www.iana.org.

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

Поля Адрес отправителя и Адрес получателя указывают IP-адреса сетевых интерфейсов отправителя и получателя. Интернет-адреса будут обсуждаться в следующем разделе.

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

Таблица 5.5. Некоторые типы необязательного поля IP-дейтаграммы

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

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

Параметр Свободная маршрутизация от источника требует, чтобы пакет прошел через указанный список маршрутизаторов в указанном порядке, но при этом по пути он может проходить через любые другие маршрутизаторы. Обычно этот параметр указывает лишь небольшое количество маршрутизаторов. Например, чтобы заставить пакет, посылаемый из Лондона в Сидней, двигаться не на восток, а на запад, можно указать в этом параметре IP-адреса маршрутизаторов в Нью-Йорке, Лос-Анджелесе и Гонолулу. Этот параметр наиболее полезен, когда по политическим или экономическим соображениям следует избегать прохождения пакетов через определенные государства.

Параметр Запомнить маршрут требует от всех маршрутизаторов, встречающихся по пути следования пакета, добавлять свой IP-адрес к полю Необязательная часть. Этот параметр позволяет системным администраторам вылавливать ошибки в алгоритмах маршрутизации («Ну почему все пакеты, посылаемые из Хьюстона в Даллас, сначала попадают в Токио?»). Когда была создана сеть ARPANET, ни один пакет не проходил больше чем через девять маршрутизаторов, поэтому размер 40 байт для этого параметра был слишком большим. Как уже говорилось, сегодня размер поля Необязательная часть оказывается слишком мал.

Наконец, параметр Временной штамп действует полностью аналогично параметру Запомнить маршрут, но кроме 32-разрядного IP-адреса, каждый маршрутизатор также записывает 32-разрядную запись о текущем времени. Этот параметр также применяется в основном для измерения параметров сети.

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

5.6.2. IP-адреса

Определяющим признаком IPv4 является его 32-битный адрес. У каждого хоста и маршрутизатора в Интернете есть IP-адрес, который может использоваться в полях Адрес отправителя и Адрес получателя IP-пакетов. Важно отметить, что IP-адрес, на самом деле, не имеет отношения к хосту. Он имеет отношение к сетевому интерфейсу, поэтому хост, соединенный с двумя сетями, должен иметь два IP-адреса. Однако на практике большинство хостов подключены к одной сети, следовательно, имеют один адрес. Маршрутизаторы, наоборот, обычно имеют несколько интерфейсов и, следовательно, несколько IP-адресов.

Префиксы

В отличие от Ethernet-адресов IP-адреса имеют иерархическую организацию. Первая часть 32-битного адреса имеет переменную длину и задает сеть, а последняя часть указывает на хост. Сетевая часть совпадает для всех хостов одной сети (например, ЛВС Ethernet). Таким образом, сети соответствует непрерывный блок пространства IP-адресов. Этот блок называется префиксом (prefix).

IP-адреса обычно записываются в виде четырех десятичных чисел (которые соответствуют отдельным байтам), разделенных точками (dotted decimal notation). Например, шестнадцатеричный адрес 80D00297 записывается как 128.208.2.151. Префикс задается наименьшим IP-адресом в блоке и размером блока. Размер определяется числом битов в сетевой части; оставшиеся биты в части хоста могут варьироваться. Таким образом, размер является степенью двойки. По традиции он пишется после префикса IP-адреса в виде слэша и длины сетевой части в битах. В нашем примере префикс содержит 28 адресов и поэтому для сетевой части отводится 24 бита. Пишется это так: 128.208.2.0/24.

Поскольку длина префикса не выводится из IP-адреса, протоколы маршрутизации вынуждены передавать префиксы на маршрутизаторы. Иногда префиксы задаются с помощью указания длины (например, «/16»). Длина префикса соответствует двоичной маске, в которой единицы указывают на сетевую часть. Такая маска называется маской подсети (subnet mask). Выполнение операции И между маской и IP-адресом позволяет выделить сетевую часть. В нашем примере (рис. 5.42) маска подсети выглядит так: 255.255.255.0. У

Рис. 5.42. Префикс IP-адреса и маска подсети

У иерархических адресов есть существенные преимущества и недостатки. Важное преимущество префиксов состоит в том, что маршрутизаторы могут направлять пакеты, используя только сетевую часть адреса, поскольку каждой сети соответствует свой уникальный адресный блок. Маршрутизатору не нужно учитывать часть адреса, задающую хост, так как пакеты для всех хостов одной сети передаются в одном направлении. Пакеты направляются на хосты только после того, как попадают в соответствующую сеть. В результате таблицы маршрутизации становятся гораздо меньше. Притом что число хостов в Интернете приближается к миллиарду, это очень существенное преимущество, так как иначе таблицы маршрутизации были бы невероятно большими. Но благодаря иерархии им приходится хранить маршруты лишь для 300 000 префиксов.

Хотя иерархия упрощает маршрутизацию в Интернете, она обладает двумя недостатками. Во-первых, IP-адрес хоста зависит от его местоположения в сети. Адреса Ethernet можно использовать в любой точке мира, а IP-адрес принадлежит конкретной сети, и поэтому маршрутизаторы могут доставить пакет, предназначенный для данного адреса, только в данную сеть. Для того чтобы хосты могли перемещаться из одной сети в другую, сохраняя свой IP-адрес, необходимы новые решения, такие как мобильный IP.

Второй недостаток состоит в том, что неправильная иерархия может привести к неэффективному использованию адресов. Если адреса приписываются сетям (слиш-

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

Подсети

Во избежание конфликтов, номера сетям назначаются некоммерческой корпорацией по присвоению имен и номеров, ICANN (Internet Corporation for Assigned Names and Numbers). В свою очередь, ICANN передала полномочия по присвоению некоторых частей адресного пространства региональным органам, занимающимся выделением IP-адресов провайдерам и другим компаниям. Таким образом компании получают блоки IP-адресов.

Однако с этого история только начинается, так как с ростом компаний им требуются новые IP-адреса. Как мы уже говорили, маршрутизация по префиксу требует, чтобы у всех хостов сети был один и тот же номер сети. Это свойство IP-адресации может вызвать проблемы при росте сети. Например, представьте, что университет создал сеть с префиксом /16 из нашего примера, используемую факультетом информатики в качестве Ethernet. Год спустя факультету электротехники понадобилось подключиться к Интернету, а затем и факультету искусств. Какие IP-адреса будут использовать эти факультеты? Если запросить дополнительные блоки, то получится, что новые сети не будут частью сети университета; к тому же, это может быть дорого и неудобно. Более того, префикс /16 позволяет подключить более 60 000 хостов. Возможно, такой префикс был выбран с учетом того, что сеть может вырасти. Но пока этого не произошло, выделять университету новые блоки будет неэффективно. Требуется новая архитектура.

Проблема решилась предоставлением сети возможности разделения на несколько частей с точки зрения внутренней организации. Это называется разбиением на подсети (subnetting). Сети, полученные в результате разбиения крупной сети (например, локальные сети в сети Ethernet), называются подсетями (subnets). Как уже упоминалось в главе 1, подобное использование этого термина конфликтует со старым понятием «подсети», обозначающим множество всех маршрутизаторов и линий связи в сети.

На рис. 5.43 показано, как разбиение на подсети может быть полезным в нашем примере. Единая сеть /16 разделена на части. Части не обязаны быть одинаковыми, но адреса должны быть распределены с учетом длины оставшейся части хоста. В нашем случае половина блока (/17) выделяется факультету информатики, четверть (/18) — факультету электротехники, восьмая часть (/19) — факультету искусств. Оставшаяся восьмая часть не используется. Еще один способ понять, как блок разбивается на части, — посмотреть на префиксы в двоичной нотации.

Информатика

10000000

11010000

1|xxxxxxx

xxxxxxxx

Электротехника

10000000

11010000

00|xxxxxx

xxxxxxxx

Искусства

10000000

11010000

011|xxxxx

xxxxxxxx

Вертикальная черта (|) обозначает границу между номером подсети и номером хоста.

Рис. 5.43. Разделение IP-префикса при разбиении на подсети

Как центральный маршрутизатор узнает, в какую из подсетей направить пришедший пакет? Здесь и могут пригодиться специфические свойства префиксов. Одним из способов является поддержание каждым маршрутизатором таблицы из 65 536 записей, говорящих о том, какую исходящую линию использовать для доступа к каждому из хостов. Но это сведет на нет основное преимущество иерархии, касающееся размеров таблиц маршрутизации. Вместо этого можно сделать так, чтобы маршрутизаторы знали маски этих подсетей.

Когда приходит пакет, маршрутизатор просматривает адрес назначения и определяет, к какой подсети он относится. Для этого маршрутизатор может выполнить операцию И от этого адреса и маски каждой из подсетей, сравнивая результат с соответствующим префиксом. Пусть у нас есть пакет с адресом 128.208.2.151. Чтобы проверить, относится ли он к факультету информатики, прибавим к нему (используя логическое И) маску 255.255.128.0, таким образом отрезав первые 17 бит (то есть

128.208.0.0). Далее сравним полученный результат с префиксом (128.208.128.0). Они не совпадают. Для факультета электротехники аналогичным образом берем первые 18 бит адреса и получаем 128.208.0.0. Это значение совпадает с префиксом, поэтому пакет передается на интерфейс, ведущий к сети факультета электротехники.

Разделение на подсети можно впоследствии изменить. Для этого потребуется обновить сведения о сетевых масках подсетей на всех маршрутизаторах сети университета. За пределами сети разделение на подсети незаметно, поэтому нет нужды с появлением каждой подсети обращаться в ICANN или изменять какие-либо внешние базы данных.

CIDR — бесклассовая междоменная маршрутизация

Даже при эффективном выделении IP-адресов проблема разрастания сети сохраняется.

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

Маршрутизаторы интернет-провайдеров и магистралей не могут позволить себе такую роскошь. Они должны знать путь к любой сети, поэтому для них не может существовать простого правила по умолчанию. Про такие магистральные маршрутизаторы говорят, что они находятся в свободной от умолчаний зоне (default-free zone) сети Интернет. Никто не знает точно, сколько всего сетей подключено к Интернету, но очевидно, что их много — возможно, порядка миллиона. Из них можно составить очень большую таблицу. Может быть, и не очень большую с точки зрения компьютерных стандартов, но представьте себе, что маршрутизатор должен просматривать ее при отправке каждого пакета, а за секунду он отправляет миллионы таких пакетов. Для обработки пакетов с такой скоростью требуются специализированные аппаратные средства и быстродействующая память; обычный компьютер для этого не подойдет.

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

Проблема таблиц маршрутизаторов может быть решена при помощи увеличения числа уровней иерархии, как это происходит в телефонных сетях. Например, если бы каждый IP-адрес содержал поля страны, штата или провинции, города, сети и номера хоста. В таком случае, каждому маршрутизатору нужно будет знать, как добраться до каждой страны, до каждого штата или провинции своей страны, каждого города своей провинции или штата и до каждой сети своего города. К сожалению, такой подход потребует существенно более 32 бит для адреса, а адресное поле будет использоваться неэффективно (для княжества Лихтенштейн будет выделено столько же разрядов, сколько для Соединенных Штатов).

К счастью, способ уменьшить размер таблиц маршрутизации все же существует. Применим тот же принцип, что и при разбиении на подсети: маршрутизатор может узнавать о расположении IP-адресов по префиксам различной длины. Но вместо того чтобы разделять сеть на подсети, мы объединим несколько коротких префиксов в один длинный. Этот процесс называется агрегацией маршрута (route aggregation). Длинный префикс, полученный в результате, иногда называют суперсетью (supernet), в противоположность подсетям с разделением блоков адресов.

При агрегации IP-адреса содержатся в префиксах различной длины. Один и тот же IP-адрес может рассматриваться одним маршрутизатором как часть блока /22 (содержащего 210 адресов), а другим — как часть более крупного блока /20 (содержащего 212 адресов). Это зависит от того, какой информацией обладает маршрутизатор. Такой метод работает и для разбиения на подсети и называется CIDR (Classless InterDomain Routing — бесклассовая междоменная маршрутизация). Последняя на сегодняшний день версия описана в RFC 4632 (Fuller и Li, 2006). Название иллюстрирует отличие от адресов, кодирующих иерархию с помощью классов, о которой мы в скором времени поговорим.

Чтобы лучше понять алгоритм маршрутизации, рассмотрим пример. Допустим, у нас есть блок из 8192 адресов, начиная с 194.24.0.0. Допустим также, что Кембриджскому университету требуется 2048 адресов и ему выделяются адреса от 194.24.0.0 до 194.24.7.255, а также маска 255.255.248.0. Это будет префикс /21. Затем Оксфордский университет запрашивает 4096 адресов. Так как блок из 4096 адресов должен располагаться на границе, кратной 4096, то ему не могут быть выделены адреса, начинающиеся с 194.24.8.0. Вместо этого он получает адреса от 194.24.16.0 до 194.24.31.255 вместе с маской 255.255.240.0. Наконец, Эдинбургский университет просит выделить ему 1024 адреса и получает адреса от 194.24.8.0 до 194.24.11.255 и маску 255.255.252.0. Все эти присвоенные адреса и маски сведены в табл. 5.6.

Таблица 5.6. Набор присвоенных IP-адресов

Университет

Первый адрес

Последний адрес

Количество

Форма записи

Кембридж

194.24.0.0

194.24.7.255

2048

194.24.0.0/21

Эдинбург

194.24.8.0

194.24.11.255

1024

194.24.8.0/22

(Свободно)

194.24.12.0

194.24.15.255

1024

194.24.12.0/22

Оксфорд

194.24.16.0

194.24.16.255

4096

194.24.16.0/20

После этого всем маршрутизаторам, находящимся в свободной от умолчаний зоне, сообщаются IP-адреса трех новых сетей. Маршрутизаторы, находящиеся рядом с этими университетами (например, в Лондоне — рис. 5.44), возможно, захотят отправлять пакеты на эти префиксы по разным исходящим линиям. Тогда они запишут эти адреса в свои таблицы маршрутизации.

Рис. 5.44. Агрегация IP-префиксов

Теперь посмотрим на эту троицу университетов с точки зрения отдаленного маршрутизатора в Нью-Йорке. Все IP-адреса, относящиеся к этим трем префиксам, должны отправляться из Нью-Йорка (или из США) в Лондон. Процесс маршрутизации в Лондоне узнает об этом и объединяет три префикса в одну агрегированную запись

194.24.0.0/19 и передает ее в Нью-Йорк. Этот префикс содержит 8 Кбайт адресов и объединяет три университета плюс 1024 свободных адреса. Агрегация позволила объединить три префикса в один, благодаря чему уменьшилось количество префиксов, о которых должен знать маршрутизатор в Нью-Йорке, и количество записей в его таблице маршрутизации.

Если агрегация включена, она производится автоматически. Этот процесс зависит от того, где какие префиксы расположены, а не от администратора, который выделяет сетям адреса. В Интернете агрегация используется очень активно, снижая размер таблиц маршрутизации примерно до 200 000 префиксов.

Дальше все становится еще интереснее: префиксы могут пересекаться. Согласно правилу, пакеты передаются в направлении самого специализированного блока, или самого длинного совпадающего префикса (longest matching prefix), в котором находится меньше всего IP-адресов. Поведение маршрутизатора в Нью-Йорке (рис. 5.45) показывает, насколько гибкой является такой тип маршрутизации. Для отправки пакетов в наши три университета Нью-Йоркский маршрутизатор использует один агрегированный префикс. Но что делать, если тот блок адресов, который раньше был свободным, теперь принадлежит сети в Сан-Франциско? Например, Нью-Йоркский маршрутизатор может хранить четыре префикса: один для Сан-Франциско и три для Лондона. Маршрутизация по самому длинному совпадающему префиксу позволяет обойтись двумя (см. рис. 5.45). Один общий префикс используется для того, чтобы направлять трафик, предназначенный для всего блока, в Лондон. Еще один специфический префикс позволяет направлять его часть в Сан-Франциско. В соответствии с правилом самого длинного совпадающего префикса, пакеты, предназначенные для IP-адресов в Сан-Франциско, будут переданы по исходящей линии, ведущей в Сан-Франциско. Пакеты, предназначенные для более крупной сети, будут направлены в Лондон.

По сути CIDR работает так. Когда прибывает пакет, необходимо определить, относится ли данный адрес к данному префиксу; для этого просматривается таблица маршрутизации. Может оказаться, что по значению подойдет несколько записей. В этом случае используется самый длинный префикс. То есть если найдено совпадение для маски /20 и /24, то для выбора исходящей линии будет использоваться запись, соответствующая /24. Однако этот процесс был бы трудоемким, если бы таблица маршрутизации просматривалась запись за записью. Вместо этого был разработан сложный алгоритм для ускорения процесса поиска адреса в таблице (Ruiz-Sanchez и др., 2001). В маршрутизаторах, предполагающих коммерческое использование, применяются специальные чипы VLSI, в которые данные алгоритмы встроены аппаратно.

Рис. 5.45. Маршрутизация по самому длинному совпадающему префиксу на Нью-Йоркском маршрутизаторе

Полноклассовая и специализированная адресация

Чтобы лучше представлять себе основные преимущества CIDR, рассмотрим метод, который использовался раньше. До 1993 года IP-адреса разделялись на 5 категорий (рис. 5.46). Такое распределение называется полноклассовой адресацией (classful addressing).

Рис. 5.46. Форматы IP-адреса

Форматы классов A, B, C и D позволяют задавать адреса до 128 сетей с 16 млн хостов в каждой, 16 384 сетей с 64 536 хостов или 2 млн сетей (например, ЛВС) с 256 хостами (хотя некоторые из них могут быть специализированными). Предусмотрен класс для многоадресной рассылки, при которой дейтаграммы рассылаются одновременно на несколько хостов. Адреса, начинающиеся с 1111, зарезервированы для будущего применения. Неплохо было бы использовать их уже сейчас, когда адресное пространство IPv4 практически закончилось. Но так как в течение долгого времени они были запрещены, многие хосты будут их отвергать — не так уж просто заставить старые хосты изменить свои привычки.

Такая структура является иерархической. Но в отличие от CIDR здесь используются фиксированные размеры блоков адресов. Существует 2 млрд адресов, но благодаря иерархической организации адресного пространства это число сократилось на миллионы. В частности, одним из виновников этого является класс сетей В. Для большинства организаций класс А с 16 млн адресов — это слишком много, а класс С с 256 адресами — слишком мало. Класс В с 65 536 адресами — это то, что нужно. В интернет-фольклоре такая дилемма известна под названием проблемы трех медведей.

Но на самом деле, и класс В слишком велик для большинства контор, которые устанавливают у себя сети. Исследования показали, что более чем в половине случаев сети класса В включают в себя менее 50 хостов. Безо всяких сомнений, всем этим организациям хватило бы и сетей класса С, однако почему-то все уверены, что в один прекрасный день маленькое предприятие вдруг разрастется настолько, что сеть выйдет за пределы 8-битного адресного пространства хостов. Сейчас, оглядываясь назад, кажется, что лучше было бы использовать в классе С 10-битную адресацию (до 1022 хостов в сети). Если бы это было так, то, возможно, большинство организаций приняло бы разумное решение устанавливать у себя сети класса С, а не В. Таких сетей могло бы быть полмиллиона, а не 16 384, как в случае сетей класса В.

Нельзя обвинять в создавшейся ситуации проектировщиков Интернета за то, что они не увеличили (или не уменьшили) адресное пространство сетей класса В. В то время, когда принималось решение о создании трех классов сетей, Интернет был инструментом научно-исследовательских организаций США (плюс несколько компаний и военных организаций, занимавшихся исследованиями с помощью сети). Никто тогда не предполагал, что Интернет станет коммерческой системой коммуникации общего пользования, соперничающей с телефонной сетью. Тогда кое-кто сказал, ничуть не сомневаясь в своей правоте: «В США около 2000 колледжей и университетов. Даже если все они подключатся к Интернету и к ним присоединятся университеты из других стран, мы никогда не превысим число 16 000, потому что высших учебных заведений по всему миру не так уж много. Зато мы будем кодировать номер хоста целым числом байт, что ускорит процесс обработки пакетов» (в то время это выполнялось исключительно программными средствами). Быть может, в один прекрасный день кто-то скажет, обвиняя разработчиков телефонной сети: «Вот идиоты! Почему они не включили номер планеты в телефонный номер?» Когда телефонные сети создавались, никто не думал, что это понадобится.

Для решения этих проблем стали создаваться подсети, обеспечивающие гибкий механизм выделения блоков адресов отдельным организациям. Позднее в употребление вошла новая схема, позволяющая уменьшить размер таблиц маршрутизации — CIDR. Сейчас биты, указывающие на класс сети (A, B или C), не используются, хотя ссылки на них в литературе встречаются все еще довольно часто.

Отказ от классов усложнил процесс маршрутизации. В старой системе, построенной на классах, маршрутизация происходила следующим образом. По прибытии пакета на маршрутизатор копия IP-адреса, извлеченного из пакета и сдвинутого вправо на 28 бит, давала 4-битный номер класса. С помощью 16-альтернативного ветвления пакеты рассортировывались на A, B, C (а также D и E): восемь случаев было зарезервировано для А, четыре для В, два для С. Затем при помощи маскировки по коду каждого класса определялся 8-, 16- или 32-битный сетевой номер, который и записывался с выравниванием по правым разрядам в 32-битное слово. Сетевой номер отыскивался в таблице А, В или С, причем для А и В применялась индексация, а для С — хэш-функция. По найденной записи определялась выходная линия, по которой пакет и отправлялся в дальнейшее путешествие. Этот метод гораздо проще, чем нахождение наиболее длинного совпадающего префикса, при котором простой поиск по таблице невозможен, так как префиксы IP-адресов могут иметь произвольную длину.

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

Некоторые адреса имеют особое назначение (рис. 5.47). IP-адрес 0.0.0.0 — наименьший адрес — используется хостом только при загрузке. Он означает «эта сеть» или «этот хост». IP-адреса с нулевым номером сети обозначают текущую сеть. Эти адреса позволяют машинам обращаться к хостам собственной сети, не зная ее номера (но

они должны знать маску сети, чтобы знать количество используемых нулей). Адрес, состоящий только из единиц, или 255.255.255.255 — наибольший адрес — обозначает все хосты в указанной сети. Он обеспечивает широковещание в пределах текущей (обычно локальной) сети. Адреса, в которых указана сеть, но в поле номера хоста одни единицы, обеспечивают широковещание в пределах любой удаленной локальной сети, соединенной с Интернетом. Однако многие сетевые администраторы отключают эту возможность по соображениям безопасности. Наконец, все адреса вида 127.xx.yy. zz зарезервированы для тестирования сетевого программного обеспечения методом обратной петли (loopback). Отправляемые по этому адресу пакеты не попадают на линию, а обрабатываются локально как входные пакеты. Это позволяет пакетам быть «посланными» на хост, когда отправитель на этом же хосте не знает его (и своего) номера и даже если хост его не имеет, что может пригодиться для тестирования.

Рис. 5.47. Специальные IP-адреса

NAT — трансляция сетевого адреса

IP-адреса являются дефицитным ресурсом. У провайдера может быть /16-адрес (бывший класс В), дающий возможность подключить 65 534 хоста. Если клиентов становится больше, начинают возникать проблемы.

Этот дефицит ресурсов стал причиной появления методов эффективного использования IP-адресов. Идея одного из подходов заключается в том, что IP-адрес выделяется компьютеру, который в данный момент включен и подключен к сети; когда этот компьютер становится неактивным, его адрес присваивается новому соединению. В таком случае один /16-адрес будет обслуживать до 65 534 активных пользователей.

Такая стратегия в некоторых ситуациях работает хорошо — например, при подключении к сети через телефон, для мобильных и других ПК, где соединение или питание могут временно отсутствовать. Но если заказчиком является организация, эта стратегия, как правило, не подходит. Дело в том, что корпоративные клиенты предпочитают, чтобы компьютеры работали постоянно. Некоторые компьютеры являются рабочими станциями сотрудников, и данные с них резервируются в ночное время, а некоторые служат веб-серверами и поэтому должны уметь незамедлительно отвечать на любой удаленный запрос. Такие организации обладают линией доступа, обеспечивающей постоянное соединение с Интернетом.

Проблема усугубляется еще и тем, что все большее число частных пользователей желают иметь ADSL или кабельное соединение с Интернетом, поскольку при этом отсутствует повременная оплата (взимается только ежемесячная абонентская плата). Многие такие пользователи имеют дома два и более компьютера (например, по одному на каждого члена семьи) и хотят, чтобы все машины имели постоянный выход в Интернет. Решение таково: необходимо установить (беспроводной) маршрутизатор и объединить все компьютеры в домашнюю локальную сеть. А уже маршрутизатор должен быть подключен к провайдеру. С точки зрения провайдера, в этом случае семья будет выступать в качестве аналога маленькой фирмы с несколькими компьютерами. Добро пожаловать в Jones, Inc! Если использовать обычные схемы, то каждый компьютер будет сохранять свой IP-адрес в течение всего дня. Но для интернет-провайдеров с несколькими тысячами клиентов (многие из которых представляют собой целые организации или семьи, также похожие на небольшие организации) такая ситуация недопустима, так как IP-адресов попросту не хватит. Проблема дефицита IP-адресов отнюдь не теоретическая и отнюдь не относится к отдаленному будущему. Она уже актуальна и бороться с ней приходится здесь и сейчас. В долгосрочной перспективе решением будет тотальный перевод всего Интернета на протокол IPv6 со 128-битной адресацией. Этот переход действительно постепенно происходит, но процесс идет настолько медленно, что затягивается на годы. Видя это, многие поняли, что нужно срочно найти какое-нибудь решение хотя бы на ближайшее время. Такое решение было найдено и сейчас широко используется: это метод трансляции сетевого адреса, NAT (Network Address Translation), описанный в RFC 3022. Суть его мы рассмотрим ниже, а более подробную информацию можно найти в (Dutcher, 2001).

Основная идея трансляции сетевого адреса состоит в присвоении каждой фирме или семье одного IP-адреса (или, по крайней мере, небольшого числа адресов) для интернет-трафика. Внутри абонентской сети каждый компьютер получает уникальный IP-адрес, используемый для маршрутизации внутреннего трафика. Однако, как только пакет покидает пределы абонентской сети и направляется к провайдеру, выполняется трансляция адреса, при которой уникальный внутренний IP-адрес становится общим публичным IP-адресом. Для реализации этой схемы было создано три диапазона так называемых частных IP-адресов. Они могут использоваться внутри сети по ее усмотрению. Единственное ограничение заключается в том, что пакеты с такими адресами ни в коем случае не должны появляться в самом Интернете. Вот эти три зарезервированных диапазона:

10.0. 0.0    -    10.255.255.255/8    (16 777 216 хостов)

172.16.0. 0    -    172.31.255.255/12    (1 048 576 хостов)

192.168.0. 0    -    192.168.255.255/16    (65 536 хостов)

Итак, первый диапазон может обеспечить адресами 16 777 216 хостов (кроме всех 0 и всех 1, как обычно), и именно его обычно предпочитают абоненты, причем даже для небольших сетей.

Работа метода трансляции сетевых адресов показана на рис. 5.48. В пределах территории абонента у каждой машины имеется собственный уникальный адрес вида 10.x.y.z. Тем не менее, перед тем как пакет выходит за пределы владений абонента, он проходит через NAT-блок (NAT box), транслирующий внутренний IP-адрес источника (10.0.0.1 на рисунке) в реальный IP-адрес, полученный абонентом от провайдера (198.60.42.12 для нашего примера). NAT-блок обычно представляет собой единое устройство с межсетевым экраном, обеспечивающим безопасность путем строгого

отслеживания входящего и исходящего трафика абонентской сети. Межсетевые экраны мы будем изучать отдельно в главе 8. NAT-блок может быть также интегрирован с маршрутизатором или модемом ADSL.

Рис. 5.48. Расположение и работа NAT-блока

Мы до сих пор обходили одну маленькую деталь: когда приходит ответ на запрос (например, от веб-сервера), он ведь адресуется 198.60.42.12. Как же NAT-блок узнает, каким внутренним адресом заменить общий адрес компании? Вот в этом и состоит главная проблема использования трансляции сетевых адресов. Если бы в заголовке IP-пакета было свободное поле, его можно было бы использовать для запоминания адреса того, кто посылал запрос. Но в заголовке остается неиспользованным всего один бит. В принципе, можно было бы создать такое поле для истинного адреса источника, но это потребовало бы изменения IP-кода на всех машинах по всему Интернету. Это не лучший выход, особенно если мы хотим найти быстрое решение проблемы нехватки IP-адресов.

На самом деле, происходит вот что. Разработчики NAT подметили, что большая часть полезной нагрузки IP-пакетов — это либо TCP, либо UDP. Когда мы будем в главе 6 рассматривать TCP и UDP, мы увидим, что оба формата имеют заголовки, содержащие номера портов источника и приемника. Ниже мы обсудим, что значит порт TCP, но надо иметь в виду, что с портами UDP связана точно такая же история. Номера портов представляют собой 16-разрядные целые числа, показывающие, где начинается и где заканчивается TCP-соединение. Место хранения номеров портов используется в качестве поля, необходимого для работы NAT.

Когда процесс желает установить TCP-соединение с удаленным процессом, он связывается со свободным TCP-портом на собственном компьютере. Этот порт становится портом источника (source port), который сообщает TCP-коду информацию о том, куда направлять пакеты данного соединения. Процесс также определяет порт назначения (destination port). Посредством порта назначения сообщается, кому отдать пакет на удаленной стороне. Порты с 0 по 1023 зарезервированы для хорошо известных сервисов. Например, 80-й порт используется веб-серверами, соответственно, на них могут ориентироваться удаленные клиенты. Каждое исходящее сообщение TCP содержит информацию о порте источника и порте назначения. Вместе они служат для идентификации процессов на обоих концах, использующих соединение.

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

С помощью поля Порт источника мы можем решить проблему отображения адресов. Когда исходящий пакет приходит в NAT-блок, адрес источника вида 10.x.y.z заменяется настоящим IP-адресом. Кроме того, поле Порт источника TCP заменяется индексом таблицы перевода NAT-блока, содержащей 65 536 записей. Каждая запись содержит исходный IP-адрес и номер исходного порта. Наконец, пересчитываются и вставляются в пакет контрольные суммы заголовков TCP и IP. Необходимо заменять поле Порт источника, потому что машины с местными адресами 10.0.0.1 и 10.0.0.2 могут случайно пожелать воспользоваться одним и тем же портом (5000-м, например). Так что для однозначной идентификации процесса отправителя одного поля Порт источника оказывается недостаточно.

Когда пакет прибывает на NAT-блок со стороны провайдера, извлекается значение поля Порт источника заголовка TCP. Оно используется в качестве индекса таблицы отображения NAT-блока. По найденной в этой таблице записи определяются внутренний IP-адрес и настоящий Порт источника TCP. Эти два значения вставляются в пакет. Затем заново подсчитываются контрольные суммы TCP и IP. Пакет передается на главный маршрутизатор абонента для нормальной доставки с адресом вида 10.x.y.z.

Хотя описанная выше схема частично решает проблему нехватки IP-адресов, сетевые пуристы из IP-сообщества рассматривают NAT как некую заразу, распространяющуюся по Земле. И их можно понять.Во-первых, сам принцип трансляции сетевых адресов никак не вписывается в архитектуру IP, которая подразумевает, что каждый IP-адрес уникальным образом идентифицирует только одну машину в мире. Вся программная структура Интернета построена на использовании этого факта. При трансляции сетевых адресов получается, что тысячи машин могут (и так происходит в действительности) иметь адрес 10.0.0.1.

Во-вторых, NAT нарушает «сквозной» принцип, согласно которому каждый хост должен уметь отправлять пакет любому другому хосту в любой момент времени. Поскольку отображение адресов в NAT-блоке задается исходящими пакетами, входящие пакеты не принимаются до тех пор, пока не отправлены исходящие. На деле это означает, что пользователь домашней сети с NAT может создать TCP/IP-соединение с удаленным сервером, но удаленный пользователь не может подключиться к игровому серверу в домашней сети. Чтобы это было возможным, необходимы специальные настройки или технология NAT Traversal.

В-третьих, NAT превращает Интернет из сети без установления соединения в нечто подобное сети, ориентированной на соединение. Проблема в том, что NAT-блок должен поддерживать таблицу отображения для всех соединений, проходящих через него. Запоминать состояние соединения — дело сетей, ориентированных на соединение, но никак не сетей без установления соединений. Если NAT-блок ломается и теряются его таблицы отображения, то про все TCP-соединения, проходящие через него, можно забыть. При отсутствии трансляции сетевых адресов выход из строя или перезагрузка маршрутизатора не оказывает никакого эффекта на TCP-соединение.

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

В-четвертых, NAT нарушает одно из фундаментальных правил построения многоуровневых протоколов: уровень k не должен строить никаких предположений относительно того, что именно уровень k + 1 поместил в поле полезной нагрузки. Этот принцип определяет независимость уровней друг от друга. Если когда-нибудь на смену ТСР придет ТСР-2, у которого будет другой формат заголовка (например, 32-битная адресация портов), то трансляция сетевых адресов потерпит фиаско. Вся идея многоуровневых протоколов состоит в том, чтобы изменения в одном из уровней никак не могли повлиять на остальные уровни. NAT разрушает эту независимость.

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

В-шестых, некоторые приложения предусматривают использование множественных TCP/IP-соединений или UDP-портов. Так, FTP, стандартный Протокол передачи файлов (File Transfer Protocol), вставляет IP-адрес в тело пакета, чтобы затем получатель извлек его оттуда и обработал. Так как NAT об этом ничего не знает, он не сможет переписать адрес или как-то иначе его обработать. Это значит, что FTP и другие приложения, такие как протокол интернет-телефонии H.323 (мы будем изучать его в главе 7), могут отказаться работать при трансляции сетевых адресов, если только не будут приняты специальные меры. Часто существует возможность улучшить метод NAT и заставить его корректно работать в таких случаях, но невозможно же дорабатывать его всякий раз, когда появляется новое приложение.

Наконец, поскольку поле Порт источника является 16-разрядным, то на один IP-адрес может быть отображено примерно 65 536 местных адресов машин. На самом деле, это число несколько меньше: первые 4096 портов зарезервированы для служебных нужд. В общем, если есть несколько IP-адресов, то каждый из них может поддерживать до 61 440 местных адресов.

Эти и другие проблемы, связанные с трансляцией сетевых адресов, обсуждаются в RFC 2993. Несмотря на все трудности, NAT представляет собой единственный работающий механизм борьбы с дефицитом IP-адресов. Поэтому он широко используется на практике, особенно в домашних сетях и сетях небольших организаций. В NAT сейчас существуют межсетевые экраны и средства обеспечения конфиденциальности, поскольку по умолчанию блокируются все незапрошенные входящие пакеты. Поэтому маловероятно, что эта технология уйдет из употребления после внедрения IPv6.

5.6.3. Протокол IP версии 6

В течение многих лет IP оставался чрезвычайно популярным протоколом. Он работал просто прекрасно, и основное подтверждение тому — экспоненциальный рост сети Интернет. К сожалению, протокол IP скоро стал жертвой собственной популярности: стало подходить к концу адресное пространство. И хотя для более эффективного использования адресного пространства стали применяться CIDR и NAT, до 2012 года IPv4^peca будут выделяться с помощью ICANN. Надвигающуюся угрозу заметили почти 20 лет назад, и вопрос о том, что с этим делать, вызвал в интернет-сообществе бурю дискуссий и расхождений.

В этом разделе мы поговорим как об этой проблеме, так и о ее решениях. В перспективе хорошей идеей является переход к более длинным адресам. IPv6 (IP version 6 IP версии 6) — новая разработка, призванная заменить старую. Протокол IPv6 использует 128-битные адреса; в обозримом будущем дополнительного увеличения длины адреса, скорее всего, не потребуется. Однако оказалось, что внедрить IPv6 не так уж просто. Это принципиально новый протокол сетевого уровня, несовместимый с IPv4, несмотря на многочисленные сходства с ним. Кроме того, компании и отдельные пользователи не понимают, почему им стоит перейти на IPv6. Поэтому сейчас он занимает лишь крохотную часть Интернета (около 1 %) несмотря на то что признан стандартом еще в 1998 году. Что будет дальше, станет ясно в ближайшие несколько лет, когда будут распределены последние из оставшихся IPv4-адресов. Интересно, станут ли люди продавать свои адреса на eBay? Или на черном рынке? Как знать.

Помимо перечисленных выше проблем с выделением адресов, имеются и другие, угрожающе вырастающие на горизонте. До недавних пор Интернетом пользовались в основном университеты, высокотехнологичные предприятия и правительственные организации США (особенно Министерство обороны). С лавинообразным ростом интереса к Интернету, начавшимся в середине 90-х годов, в третьем тысячелетии, скорее всего, им будет пользоваться гораздо большее количество пользователей с принципиально разными требованиями. Во-первых, пользователи смартфонов могут подключаться к Интернету для доступа к домашним базам данных. Во-вторых, при неминуемом сближении компьютерной промышленности, средств связи и индустрии развлечений, возможно, очень скоро каждый телефон и телевизор планеты станет узлом Интернета, что в результате приведет к появлению миллиардов машин, используемых для аудио и видео по заказу. В таких обстоятельствах становится очевидно, что протокол IP должен эволюционировать и стать более гибким.

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

1.    Поддержка миллиардов хостов даже при неэффективном использовании адресного пространства.

2.    Уменьшение размера таблиц маршрутизации.

3.    Упрощение протокола для ускорения обработки пакетов маршрутизаторами.

4.    Более надежное обеспечение безопасности (аутентификации и конфиденциальности).

5.    Необходимость обращать большее внимание на тип сервиса, в частности, при передаче данных реального времени.

6.    Упрощение работы многоадресных рассылок с помощью указания областей рассылки.

7.    Возможность изменения положения хоста без необходимости изменять его адрес.

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

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

лет.

Разработка IPv6 дала шанс улучшить возможности IPv4 исходя из потребностей современного Интернета. Чтобы найти протокол, удовлетворяющий всем этим требованиям, IETF издал в RFC 1550 приглашение к дискуссиям и предложениям. Был получен двадцать один ответ. Далеко не все варианты содержали предложения, полностью удовлетворяющие этим требованиям. В декабре 1992 года были рассмотрены семь серьезных предложений. Их содержание варьировалось от небольших изменений в протоколе IP до полного отказа от него и замены совершенно другим протоколом.

Одно из предложений состояло в использовании вместо IP протокола CLNP, который с его 160-разрядным адресом обеспечивал бы достаточное адресное пространство на веки вечные — этого пространства хватило бы, если бы каждая молекула воды в мировом океане захотела создать свою небольшую сеть (порядка 25 адресов). Кроме того, это решение объединило бы два основных сетевых протокола. Однако все же сочли, что при подобном выборе придется признать, что кое-что в мире OSI было сделано правильно, что было бы политически некорректным в интернет-кругах. Протокол CLNP, на самом деле, очень мало отличается от протокола IP. Окончательный выбор был сделан в пользу протокола, отличающегося от IP значительно сильнее, нежели CLNP. Еще одним аргументом против CLNP была его слабая поддержка типа сервиса, требовавшегося для эффективной передачи мультимедиа.

Три лучших предложения были опубликованы в журнале IEEE Network Magazine (Deering, 1993; Francis, 1993; Katz и Ford, 1993). После долгих обсуждений, переработок и борьбы за первое место была выбрана модифицированная комбинированная версия Диринга (Deering) и Фрэнсиса (Francis), называемая в настоящий момент протоколом SIPP (Simple Internet Protocol Plus — Простой интернет-протокол Плюс). Новому протоколу было дано обозначение IPv6.

Протокол IPv6 прекрасно справляется с поставленными задачами. Он обладает достоинствами протокола IP и лишен некоторых его недостатков (либо обладает ими в меньшей степени), к тому же наделен некоторыми новыми особенностями. В общем случае, протокол IPv6 несовместим с протоколом IPv4, но зато совместим со всеми остальными протоколами Интернета, включая TCP, UDP, ICMP, IGMP, OSPF, BGP и DNS, для чего иногда требуются небольшие изменения для работы с более длинными адресами. Основные особенности протокола IPv6 обсуждаются ниже. Дополнительные сведения о нем можно найти в RFC с 2460 по 2466.

Прежде всего, у протокола IPv6 поля адресов длиннее, чем у IPv4. Они имеют длину 128 бит, что решает основную проблему, поставленную при разработке протокола, — обеспечить практически неограниченный запас интернет-адресов. Мы еще кратко упомянем об адресах чуть позднее.

Второе заметное улучшение протокола IPv6 по сравнению с IPv4 состоит в более простом заголовке пакета. Он состоит всего из 7 полей (вместо 13 у протокола IPv4). Таким образом, маршрутизаторы могут быстрее обрабатывать пакеты, что повышает производительность. Краткое описание заголовков будет приведено ниже.

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

В-четвертых, протокол IPv6 демонстрирует большой шаг вперед в области безопасности. У проблемной группы проектирования Интернета IETF была полная папка вырезок из газет с сообщениями о том, как 12-летние мальчишки с помощью своего персонального компьютера по Интернету вломились в банк или военную базу. Было ясно, что надо как-то улучшить систему безопасности. Аутентификация и конфиденциальность являются ключевыми чертами нового IP-протокола. После модификации IPv4 разница с точки зрения безопасности стала не так уж и велика.

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

Основной заголовок IPv6

Заголовок IPv6 показан на рис. 5.49. Поле Версиясодержит число 6 для IPv6 (и 4 для IPv4). На период перехода с IPv4 на IPv6, который, вероятно, займет около десяти лет, маршрутизаторы по значению этого поля смогут отличать пакеты нового стандарта от старого. Подобная проверка потребует нескольких тактов процессора, что может оказаться нежелательным в некоторых ситуациях, тем более что в заголовке с информацией о канале передачи данных обычно указан протокол для демультиплексирования, так что эту проверку можно пропустить. Например, в Ethernet у поля Типсуществует несколько разных значений, определяющих полезные данные IPv4- или IPv6-пакета. Дискуссия между лагерями, руководствующимися принципами «Делай правильно» и «Делай быстро», несомненно, будет долгой и энергичной.

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

Поле Метка потокаприменяется для того, чтобы отправитель и получатель могли сообщить сети об определенных свойствах пакетов и требованиях к их обработке; при этом между ними устанавливается псевдосоединение. Например, поток пакетов между двумя процессами на разных хостах может обладать строгими требованиями к задержкам, что потребует резервирования пропускной способности. Поток устанавливается заранее и получает идентификатор. Когда прибывает пакет с отличным от нуля содержимым поля Метка потока, все маршрутизаторы смотрят в свои таблицы, чтобы определить, какого рода особая обработка ему требуется. Таким образом, новый протокол пытается соединить достоинства подсетей различных типов: гибкость дейтаграмм и гарантии виртуальных каналов.

Рис. 5.49. Фиксированный заголовок IPv6 (обязательные поля)

С целью обеспечения должного качества обслуживания каждый поток описывается адресом источника, адресом назначения и номером потока. Это значит, что для каждой пары IP-адресов можно создать до 220 активных потоков. Кроме того, два потока с одинаковыми номерами, но различными адресами отправителя или получателя считаются разными потоками и различаются маршрутизаторами по адресам. Ожидается, что номера каналов будут выбираться случайным образом, а не назначаться подряд начиная с 1, что облегчит маршрутизаторам их распознавание.

Поле Длина полезной нагрузки сообщает, сколько байт следует за 40-байтовым заголовком, показанным на рис. 5.49. В заголовке IPv4 аналогичное поле называлось Полная длина и определяло весь размер пакета. В новом протоколе 40 байт заголовка учитываются отдельно. Это значит, что теперь полезная нагрузка может занимать 65 535 байт вместо 65 515.

Поле Следующий заголовок раскрывает секрет возможности использования упрощенного заголовка. Дело в том, что после обычного 40-байтового заголовка могут идти дополнительные (необязательные) расширенные заголовки. Это поле сообщает, какой из шести дополнительных заголовков (на текущий момент) следует за основным. В последнем IP-заголовке поле Следующий заголовок сообщает, какой обрабатывающей программе протокола транспортного уровня (то есть TCP или UDP) передать пакет.

Поле Максимальное число транзитных участков не дает пакетам вечно блуждать по сети. Оно имеет практически то же назначение, что и поле Время жизни в заголовке протокола IPv4. Это поле уменьшается на единицу на каждом транзитном участке. Теоретически, в протоколе IPv4 это поле должно было содержать секунды времени жизни пакета, однако ни один маршрутизатор не использовал его подобным образом, поэтому имя поля было приведено в соответствие со способом его применения.

Следом идут поля Адрес отправителя и Адрес получателя. В исходном предложении Диринга (протоколе SIPP) использовались 8-байтовые адреса, но при рассмотрении проекта было решено, что 8-байтовых адресов хватит лишь на несколько десятилетий, в то время как 16-байтовых адресов должно хватить навечно. Другие возражали, что 16 байт для адресов слишком много, тогда как третьи настаивали на 20-байтных адресах для совместимости с дейтаграммным протоколом OSI. Еще одна фракция ратовала за адреса переменной длины. После продолжительных споров, содержащих непечатную лексику, было решено, что наилучшим компромиссным решением являются 16-байтовые адреса фиксированной длины.

Для написания 16-байтовых адресов была выработана новая нотация. Адреса в IPv6 записываются в виде восьми групп по четыре шестнадцатеричных цифры, разделенных двоеточиями, например:

8000:0000:0000:0000:0123:4567:89AB:CDEF

Поскольку многие адреса будут содержать большое количество нулей, были разрешены три метода сокращенной записи адресов. Во-первых, могут быть опущены ведущие нули в каждой группе, например 0123 можно записывать как 123. Во-вторых, одна или более групп, полностью состоящих из нулей, могут заменяться парой двоеточий. Таким образом, приведенный выше адрес принимает вид:

8000::123:4567:89AB:CDEF

Наконец, адреса IPv4 могут записываться как пара двоеточий, после которой пишется адрес в старом десятичном формате, например:

::192.31.20.46

Возможно, об этом нет необходимости говорить столь подробно, но количество всех возможных 16-байтовых адресов очень велико — 2128, что приблизительно равно 3 х 1023 IP-адресов на квадратный метр. Кто изучал химию, может заметить, что это число больше числа Авогадро. Хотя в планы разработчиков не входило предоставление собственного IP-адреса каждой молекуле на поверхности Земли, они оказались не так далеко от обеспечения такой услуги.

На практике не все адресное пространство используется эффективно, как, например, не используются абсолютно все комбинации телефонных номеров. Например, телефонные номера Манхеттена (код 212) почти полностью заняты, тогда как в штате Вайоминг (код 307) они почти не используются. В RFC 3194 Дьюранд (Durand) и Хуй-тема (Huitema) приводят свои вычисления. Утверждается, что если ориентироваться на использование телефонных номеров, то даже при самом пессимистическом сценарии все равно получается более 1000 IP-адресов на квадратный метр поверхности Земли (включая как сушу, так и море). При любом более вероятном сценарии обеспечиваются триллионы адресов на квадратный метр. Таким образом, маловероятно, что в обозримом будущем обнаружится нехватка адресов.

Полезно сравнить заголовок IPv4 (см. рис. 5.41) с заголовком IPv6 (рис. 5.49), чтобы увидеть, что осталось от старого стандарта. Поле IHL исчезло, так как заголовок IPv6 имеет фиксированную длину. Поле Протокол также было убрано, поскольку поле Следующий заголовок сообщает, что следует за последним IP-заголовком (то есть UDP или TCP-сегмент).

Были удалены все поля, относящиеся к фрагментации, так как в протоколе IPv6 используется другой подход к фрагментации. Во-первых, все хосты, поддерживающие протокол IPv6, должны динамически определять нужный размер пакета. Для этого используется технология Path MTU discovery, о которой мы говорили в разделе 5.5.5. Вкратце, когда хост посылает слишком большой IPv6-пакет, вместо того чтобы его фрагментировать, то маршрутизатор, неспособный переслать пакет дальше, посылает обратно сообщение об ошибке. Получив это сообщение, хост должен прекратить всю передачу этому адресату. Гораздо правильнее будет научить все хосты посылать пакеты требуемого размера, нежели учить маршрутизаторы фрагментировать их на лету. Кроме того, минимальный размер пакета был увеличен с 576 до 1280, чтобы можно было передавать 1024 байт данных, плюс множество заголовков.

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

Дополнительные заголовки

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

Таблица 5.7. Дополнительные заголовки IPv6

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

варианта: пропустить параметр, игнорировать пакет, игнорировать пакет и отослать обратно ICMP-пакет, а также то же самое, что и предыдущий вариант, но не отсылать обратно ICMP-пакет в случае многоадресной рассылки (чтобы один неверный многоадресный пакет не породил миллионы ICMP-донесений).

Поле Длина также имеет размер 1 байт. Оно сообщает, насколько велико значение (от 0 до 255 байт). Поле Значение содержит необходимую информацию размером до 255 байт.

Заголовок параметров маршрутизации содержит информацию, которую должны исследовать маршрутизаторы на протяжении всего пути следования пакета. Пока что был определен один вариант использования этого параметра: поддержка дейтаграмм, превышающих 64 Кбайт. Формат заголовка показан на рис. 5.50. При этом полю Длина полезной нагрузки в фиксированном заголовке присваивается значение 0.

Следующий заголовок

0

194

4

Длина полезной нагрузки

Рис. 5.50. Дополнительный заголовок для больших дейтаграмм

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

Следующие два байта указывают, что данный параметр содержит размер дейтаграммы (код 194) в виде 4-байтового числа. Размеры меньше 65 536 не допускаются, так как могут привести к тому, что первый же маршрутизатор проигнорирует данный пакет и отошлет обратно ICMP-сообщение об ошибке. Дейтаграммы, использующие подобные расширения заголовка, называются джамбограммами (jumbograms, от слова «jumbo», означающего нечто большое и неуклюжее). Использование джамбограмм важно для суперкомпьютерных приложений, которым необходимо эффективно передавать по Интернету гигабайты данных.

Заголовок расширяется на поля, которые должны инетерпретироваться только хостом-получателем. В начальной версии IPv6 задавались только «нулевые» настройки для дополнения этого заголовка до кратности 8 байтам, и сам заголовок не использовался. Это делалась для того, чтобы программное обеспечение новых роутеров и хостов могло их обработать, если кто-нибудь подумает о дополнительных настройках в будущем.

Маршрутный заголовок содержит информацию об одном или нескольких маршрутизаторах, которые следует посетить по пути к получателю. Это очень сильно напоминает свободную маршрутизацию стандарта IPv4 в том, что указанные в списке маршрутизаторы должны быть пройдены строго по порядку, тогда как не указанные проходятся между ними. Формат маршрутного заголовка показан на рис. 5.51.

Первые четыре байта дополнительного маршрутного заголовка содержат четыре однобайтовых целых числа. Поля Следующий заголовок и Длина дополнительного заголовка были описаны ранее. В поле Тип маршрутизации описывается формат оставшейся части заголовка. Если он равен 0, это означает, что далее следует зарезервированное 32-разрядное слово, а за ним — некоторое число адресов IPv6. В бу-

дущем, возможно, будут по мере необходимости изобретаться какие-то новые поля. Наконец, в поле Число оставшихся сегментов указывается, сколько адресов из списка еще осталось посетить. Его значение уменьшается при прохождении каждого адреса. Когда оно достигает нуля, пакет оставляется на произвол судьбы — никаких указаний относительно его дальнейшего маршрута не дается. Обычно в этот момент пакет уже находится достаточно близко к месту назначения, и оптимальный маршрут очевиден.

Рис. 5.51. Дополнительный заголовок для маршрутизации

Заголовок фрагментации определяет фрагментацию способом, схожим с протоколом IPv4. Заголовок содержит идентификатор дейтаграммы, номер фрагмента и бит, информирующий о том, является ли этот фрагмент последним. В отличие от IPv4 в протоколе IPv6 фрагментировать пакет может только хост-источник. Маршрутизаторы фрагментировать пересылаемые пакеты не могут. Хотя это изменение можно считать отказом от оригинальной философии IP, оно вполне в духе современного применения IPv4. Вдобавок оно упрощает и ускоряет работу маршрутизаторов. Как уже было сказано, маршрутизатор отвергает слишком большие пакеты, посылая в ответ ICMP-пакет, указывающий хосту-источнику на необходимость заново передать пакет, выполнив его фрагментацию на меньшие части.

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

Полемика

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

О спорах по поводу длины поля адреса уже упоминалось. В результате было принято компромиссное решение: 16-байтовые адреса фиксированной длины.

Другое сражение разгорелось из-за размера поля Максимальное количество транзитных участков. Один из противостоящих друг другу лагерей считал, что ограничение количества транзитных участков числом 255 (это явно следует из использования 8-битного поля) является большой ошибкой. В самом деле, маршруты из 32 транзитных участков уже стали обычными, а через 10 лет могут стать обычными более длинные маршруты. Сторонники этого лагеря заявляли, что использование полей адресов огромного размера было решением дальновидным, а крохотных счетчиков транзитных участков — недальновидным. Самый страшный грех, который, по их мнению, могут совершить специалисты по вычислительной технике, — это выделить для чего-нибудь недостаточное количество разрядов.

В ответ им было заявлено, что подобные аргументы можно привести для увеличения любого поля, что приведет к разбуханию заголовка. Кроме того, назначение поля Максимальное количество транзитных участков состоит в том, чтобы не допустить слишком долгого странствования пакетов, и 65 535 транзитных участков — это очень много. К тому же, по мере роста Интернета будет создаваться все большее количество междугородных линий, что позволит передавать пакеты из любой страны в любую страну максимум за шесть транзитных пересылок. Если от получателя или отправителя до соответствующего международного шлюза окажется более 125 транзитных участков, то, видимо, что-то не в порядке с магистралями этого государства. В итоге эту битву выиграли сторонники 8-битового счетчика.

Еще одним предметом спора оказался максимальный размер пакета. Обладатели суперкомпьютеров настаивали на размере пакетов, превышающем 64 Кбайт. Когда суперкомпьютер начинает передачу, он занимается серьезным делом и не хочет, чтобы его прерывали через каждые 64 Кбайта. Аргумент против больших пакетов заключается в том, что если пакет размером в 1 Мбайт будет передаваться по линии Т1 со скоростью 1,5 Мбит/с, то он займет линию на целых 5 с, что вызовет слишком большую задержку, заметную для интерактивных пользователей. В данном вопросе удалось достичь компромисса: нормальные пакеты ограничены размером 64 Кбайт, но с помощью дополнительного заголовка можно пересылать дейтаграммы огромного размера.

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

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

Вокруг мобильных хостов также разгорелся спор. Если мобильный компьютер окажется на другом конце Земли, сможет ли он продолжать использовать прежний IPv6-адрес, или он должен будет использовать схему с внутренним и внешним агентами? Появилось много желающих создать в протоколе IPv6 явную поддержку мобильных хостов. Эти попытки потерпели поражение, поскольку ни по одному конкретному предложению не удалось достичь консенсуса.

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

Другой аспект вопроса расположения системы безопасности касается того факта, что во многих (но не во всех) странах приняты строгие экспортные законы, касающиеся криптографии. В некоторых странах, особенно во Франции и Ираке, строго запрещено использование криптографии даже внутри страны, чтобы у населения не могло быть секретов от полиции. В результате любая реализация протокола IP, использующая достаточно мощную криптографическую систему, не может быть экспортирована за пределы Соединенных Штатов (и многих других стран). Таким образом, приходится поддерживать два набора программного обеспечения — один для внутреннего использования и другой для экспорта, против чего решительно выступает большинство производителей компьютеров.

Единственный вопрос, по которому не было споров, состоял в том, что никто не ожидает, что IPv4-интернет будет выключен в воскресенье, а в понедельник утром будет включен уже IPv6-интернет. Вместо этого вначале появятся «островки» IPv6, которые будут общаться по туннелям (см. раздел 5.5.3). По мере своего роста, острова IPv6 будут объединяться в более крупные острова. Наконец, все острова объединятся, и Интернет окажется полностью трансформированным.

Так, по крайней мере, выглядел план. Внедрение IPv6 оказалось его ахиллесовой пятой. Этот протокол до сих пор очень мало используется, хотя большинство операционных систем полностью поддерживают его. Как правило, IPv6 применяется в тех случаях, когда оператору какой-либо сети — например, мобильной — требуются дополнительные IP-адреса. Чтобы упростить переход к новому протоколу, было придумано много разных стратегий. Среди них методы автоматической настройки туннелей, обеспечивающих передачу IPv6-пакетов через сеть IPv4, и технологии, позволяющие хостам автоматически находить конечную точку туннеля. Двухстековые хосты поддерживают как IPv4, так и IPv6 и могут выбирать протокол в зависимости от адреса назначения пакета. Эти стратегии помогут ускорить процесс перехода к IPv6, когда он будет неизбежным. Более подробно об этом можно прочитать в книге (Davies, 2008).

5.6.4. Управляющие протоколы Интернета

Помимо протокола IP, используемого для передачи данных, в Интернете есть несколько дополнительных управляющих протоколов, применяемых на сетевом уровне, к которым относятся ICMP, ARP и DHCP. В данном разделе мы рассмотрим их все по очереди, описывая те версии, которые соответствуют IPv4 (так как именно они сейчас широко применяются). У ICMP и DHCP существуют аналогичные версии для IPv6; эквивалентом APR является NDP (Neighbor Discovery Protocol — протокол обнаружения соседей).

ICMP — протокол управляющих сообщений Интернета

За работой Интернета следят маршрутизаторы. Если во время обработки пакета маршрутизатором случается что-то неожиданное, о происшествии сообщается по протоколу ICMP (Internet Control Message Protocol протокол управляющих сообщений Интернета), используемому также для тестирования Интернета. Протоколом ICMP определено около дюжины типов сообщений. Каждое ICMP-сообщение вкладывается в IP-пакет. Наиболее важные из них приведены в табл. 5.8.

Таблица 5.8. Основные типы ICMP-сообщений

Сообщение АДРЕСАТ НЕДОСТУПЕН (DESTINATION UNREACHABLE) используется, когда маршрутизатор не может обнаружить пункт назначения, или когда пакет с битом DF (не фрагментировать) не может быть доставлен, так как путь ему преграждает сеть с маленьким размером пакетов.

Сообщение ВРЕМЯ ИСТЕКЛО (TIME EXCEEDED) посылается, когда пакет игнорируется, так как его счетчик Время жизни уменьшился до нуля. Это событие является признаком того, что пакеты двигаются по замкнутым контурам или что установлено слишком низкое значение таймера.

Хитрый способ использования этого сообщения, предложенный Ван Джейкобсоном в 1987 году, — утилита traceroute. Она находит маршрутизаторы, расположенные в узлах пути от хоста к адресу назначения. При этом ей не требуется особый уровень поддержки. Метод состоит в отправке на адрес назначения последовательности пакетов с временем жизни 1, 2, 3 и т. д. Маршрутизаторы, на которых счетчики достигают нуля, располагаются в том порядке, в котором пакет проходит их при пересылке. Эти маршрутизаторы послушно отправляют обратно на хост сообщения ВРЕМЯ ИСТЕКЛО. По этим сообщениям хост определяет их IP-адреса и получает информацию о пути. Сообщение ВРЕМЯ ИСТЕКЛО, конечно, предназначалось не для этого. Но вполне возможно, что это самый полезный инструмент отладки сети всех времен.

Сообщение ПРОБЛЕМА ПАРАМЕТРА (PARAMETER PROBLEM) указывает на то, что обнаружено неверное значение в поле заголовка. Это является признаком наличия ошибки в программном обеспечении хоста, отправившего этот пакет, или промежуточного маршрутизатора.

Сообщение ГАШЕНИЕ ИСТОЧНИКА (SOURCE QUENCH) ранее использовалось для усмирения хостов, которые отправляли слишком много пакетов. Хост, получивший такое сообщение, должен был снизить обороты. В настоящее время подобное сообщение редко используется, так как при возникновении перегрузки подобные пакеты только подливают масла в огонь, еще больше загружая сеть. К тому же, не ясно, как на них отвечать. Теперь борьба с перегрузкой в Интернете осуществляется в основном на транспортном уровне; при этом сигналом перегрузки является утеря пакетов. Это будет подробно обсуждаться в главе 6.

Сообщение ПЕРЕАДРЕСОВАТЬ (REDIRECT) посылается хосту, отправившему пакет, когда маршрутизатор замечает, что пакет адресован неверно. Таким образом маршрутизатор предлагает хосту обновить маршрут.

Сообщения ЗАПРОС ОТКЛИКА (ECHO) и ОТКЛИК (ECHO REPLY) посылаются, чтобы определить, достижим ли и жив ли в данный момент конкретный адресат. Получив сообщение ЗАПРОС ОТКЛИКА, хост должен отправить обратно сообщение ОТКЛИК. Эти сообщения используются утилитой ping, которая проверяет, включен ли хост и подключен ли он к Интернету.

Сообщения ЗАПРОС ВРЕМЕННОГО ШТАМПА (TIMESTAMP REQUEST) и ОТКЛИК С ВРЕМЕННЫМ ШТАМПОМ (TIMESTAMP REPLY) имеют то же назначение, но при этом в ответе проставляется время получения сообщения и время отправления ответа. Это сообщение используется для измерения производительности сети.

Сообщения ОБЪЯВЛЕНИЕ МАРШРУТИЗАТОРА (ROUTER ADVERTISEMENT) и ЗАПРОС К МАРШРУТИЗАТОРУ (ROUTER SOLICITATION) позволяют хостам находить близлежащие маршрутизаторы. Хосту необходимо знать IP-адрес хотя бы одного из таких маршрутизаторов, чтобы он мог передавать пакеты за пределы локальной сети.

Кроме перечисленных сообщений определены и другие. Их полный список хранится в Интернете по адресу www.iana.org/assignments/icmp-parameters.

ARP — протокол разрешения адресов

Хотя у каждой машины в Интернете есть один или более IP-адресов, их недостаточно для отправки пакетов. Сетевые карты канального уровня, такие как Ethernet-карты, не понимают интернет-адресов. Например, каждая когда-либо выпущенная сетевая карта Ethernet имеет 48-разрядный Ethernet-адрес. Производители сетевых карт Ethernet запрашивают у IEEE блок адресов, что гарантирует уникальность Ethernet-адресов (это позволяет избежать конфликтов при наличии одинаковых сетевых карт в одной ЛВС). Сетевые карты отправляют и принимают кадры, основываясь на 48-разрядных Ethernet-адресах. О 32-разрядных IP-адресах им ничего не известно.

Таким образом, возникает вопрос: как устанавливается соответствие IP-адресов и адресов уровня передачи данных, таких как Ethernet-адреса? Чтобы понять, как это работает, рассмотрим показанный на рис. 5.52 пример, в котором изображен небольшой университет с двумя сетями /24. На рисунке мы видим две коммутируемые сети Ethernet: одна сеть (CS) на факультете кибернетики, с префиксом 192.31.65.0/24, а другая ЛВС (EE) — с префиксом 192.31.63.0/24 на электротехническом факультете. Они соединены IP-маршрутизатором. У каждой машины сетей Ethernet и у каждого интерфейса на маршрутизаторе есть уникальный Ethernet-адрес (на рисунке — от E1 до E6), и уникальный IP-адрес в сети CS или EE.

Рассмотрим, как пользователь хоста 1 посылает пакет пользователю хоста 2 в сети CS. Допустим, отправителю известно имя получателя, например eagle.cs.uni. edu. Сначала надо найти IP-адрес для хоста 2. Этот поиск осуществляется службой имен доменов DNS (Domain Name System), которую мы рассмотрим в главе 7. На данный момент мы просто предположим, что служба DNS возвращает IP-адрес для хоста 2 (192.31.65.5).

Теперь программное обеспечение верхнего уровня хоста 1 создает пакет со значением 192.31.65.5 в поле Адрес получателя и передает его IP-программе для пересылки. Программное обеспечение протокола IP может посмотреть на адрес и увидеть, что адресат находится в сети CS (то есть в его собственной сети), но ему нужно как-то определить Ethernet-адрес получателя. Одно из решений состоит в том, чтобы хранить в системе конфигурационный файл, в котором были бы перечислены соответствия всех локальных IP-адресов Ethernet-адресам. Такое решение, конечно, возможно, но в организациях с тысячами машин обновление этих файлов потребует много времени и подвержено ошибкам.

Рис. 5.52. Две коммутируемые ЛВС Ethernet, соединенные маршрутизатором

Более удачное решение заключается в рассылке хостом 1 по сети Ethernet широковещательного пакета с вопросом: «Кому принадлежит IP-адрес 192.31.65.5?» Этот пакет будет получен каждой машиной сети CS Ethernet и каждая проверит его IP-адрес. Только хост 2 ответит на вопрос своим Ethernet-адресом E2. Таким образом, хост 1 узнает, что IP-адрес 192.31.65.5 принадлежит хосту с Ethernet-адресом E2. Протокол, который задает подобный вопрос и получает ответ на него, называется ARP (Address Resolution Protocol протокол разрешения адресов) и описан в RFC 826. Он работает почти на каждой машине в Интернете.

Преимущество протокола ARP над файлами конфигурации заключается в его простоте. Системный администратор должен всего лишь назначить каждой машине IP-адрес и решить вопрос с маской подсети. Все остальное сделает протокол ARP.

Затем программное обеспечение протокола IP хоста 1 создает Ethernet-кадр для E2, помещает в его поле полезной нагрузки IP-пакет, адресованный 192.31.65.5, и посылает его по сети Ethernet. IP- и Ethernet-адреса этого пакета приведены на рис. 5.52. Сетевая карта Ethernet хоста 2 обнаруживает кадр, замечает, что он адресован ей, считывает его и вызывает прерывание. Ethernet-драйвер извлекает IP-пакет из поля полезной нагрузки и передает его IP-программе, которая, видя, что пакет адресован правильно, обрабатывает его.

Существуют различные методы повышения эффективности протокола ARP. Во-первых, машина, на которой работает протокол ARP, может запоминать результат преобразования адреса на случай, если ей придется снова связываться с той же машиной. В следующий раз она найдет нужный адрес в своем кэше, сэкономив, таким образом, на рассылке широковещательного пакета. Скорее всего, хосту 2 понадобится отослать ответ на пакет, что также потребует от него обращения к ARP для определения адреса отправителя. Этого обращения можно избежать, если отправитель включит в ARP-пакет свои IP- и Ethernet-адреса. Когда широковещательный ARP-пакет прибудет на хост 2, пара (192.31.65.7, E1) будет сохранена хостом 2 в ARP-кэше для будущего использования. Более того, эту пару адресов могут сохранить у себя все машины сети Ethernet.

Чтобы разрешить изменение соответствий адресов, например, если хост использует новый IP-адрес (но Ethernet-адрес остается прежним), записи в ARP-кэше должны устаревать за несколько минут. Существует хороший способ поддержания актуальности информации об адресах в кэше, улучшая при этом производительность. Идея в том, что каждая машина может рассылать свою пару адресов во время настройки. Обычно эта широковещательная рассылка производится в виде ARP-пакета, запрашивающего свой собственный IP-адрес. Ответа на такой запрос быть не должно, но все машины могут запомнить эту пару адресов. Это называется добровольным ARP-сообщением (gratuitous ARP). Если ответ все же (неожиданно) придет, это будет означать, что двум машинам назначен один и тот же IP-адрес. Эти машины не смогут пользоваться сетью, пока проблема не будет решена системным администратором.

Посмотрим снова на рис. 5.52. Пусть на этот раз хост 1 хочет послать пакет хосту 4 (192.31.63.8) в сети EE. Хост 1 увидит, что IP-адрес получателя не относится к сети CS. Он знает, что такие внешние пакеты нужно передавать на маршрутизатор, который иногда называют шлюзом по умолчанию (default gateway). По соглашению принято, что шлюз по умолчанию имеет наименьший адрес сети (198.31.65.1). Но чтобы отправить кадр на этот маршрутизатор, хост 1 должен знать еще и Ethernet-адрес интерфейса маршрутизатора в сети CS. Поэтому он отправляет широковещательный ARP-пакет для 198.31.65.1 и узнает E3. После этого он отправляет кадр. Аналогичным образом пакеты передаются от одного маршрутизатора к другому на всем пути до места назначения.

Когда сетевая карта Ethernet получает этот кадр, она передает пакет на обработку программным средствам IP. По сетевым маскам маршрутизатор понимает, что пакет должен быть доставлен на хост 4 в сети EE. Если ему неизвестен Ethernet-адрес хоста 4, он снова будет использовать ARP. В таблице на рис. 5.52 приведен список Ethernet- и IP-адресов из кадров сетей CS и EE. Обратите внимание на то, что для одного кадра в разных сетях Ethernet-адреса меняются, а IP-адреса — нет (так как они указывают на конечную точку во всех объединенных сетях).

Существует способ передать пакет от хоста 1 хосту 4 так, чтобы отправитель не знал, что получатель находится в другой сети. Для этого нужно, чтобы маршрутизатор отвечал на ARP-запросы сети CS для хоста 4, передавая при этом свой Ethernet-адрес E3. Хост 4 не ответит, так как не увидит широковещательного пакета (маршрутизаторы не переправляют широковещательные пакеты Ethernet-уровня). В результате маршрутизатор получит кадры для 192.32.63.8 и передаст их в сеть EE. Такой метод называется ARP-прокси (ARP-proxy). Он используется в особых случаях, когда хосту требуется сымитировать свое присутствие в какой-либо сети. Например, если портативному компьютеру нужен еще один узел, который принимал бы пакеты для него, когда компьютер находится вне домашней сети.

Протокол динамической конфигурации узла DHCP

Протокол ARP (как и другие интернет-протоколы) предполагает, что хосты обладают базовыми сведениями, например, знают свой IP-адрес. Но как хосты получают эту информацию? Можно настраивать их вручную, это очень трудоемкий процесс, к тому же часто приводящий к ошибкам. Есть более удобный способ: он называется DHCP (Dynamic Host Configuration Protocol протокол динамической настройки хостов).

Каждая сеть должна иметь DHCP-сервер, отвечающий за настройки. При запуске у каждого компьютера есть встроенный в сетевую карту Ethernet-адрес или другой адрес канального уровня, но нет IP-адреса. Для отыскания своего IP-адреса компьютер широковещательным способом распространяет специальный пакет DHCP DISCOVER. Он должен прибыть на DHCP-сервер. Если этот сервер не подключен к сети напрямую, пакет будет ретранслирован на DHCP-сервер независимо от того, где он находится.

Когда сервер получает пакет, он выделяет свободный IP-адрес и отправляет его обратно с помощью пакета DHCP OFFER (который также может ретранслироваться). Чтобы это было возможным, даже если у хоста нет IP-адреса, сервер определяет хост по его Ethernet-адресу (который содержится в пакете DHCP DISCOVER).

Встает вопрос: на какое время можно выдавать в автоматическом режиме IP-адреса из пула? Если хост покинет сеть и не освободит захваченный адрес, этот адрес будет навсегда утерян. С течением времени будет теряться все больше адресов. Для предотвращения этих неприятностей нужно выдавать IP-адреса не навсегда, а на определенное время. Такая технология называется лизингом (leasing). Перед окончанием срока действия лизинга хост должен послать на DHCP-сервер запрос о продлении срока пользования IP-адресом. Если такой запрос не был сделан или в просьбе было отказано, хост не имеет права продолжать использование выданного ранее адреса.

Протокол DHCP описан в RFC 2131 и 2132. Он широко используется в Интернете для настройки ряда параметров и приписывания IP-адресов. Помимо сетей предприятий и домашних сетей, DHCP используют интернет-провайдеры. С его помощью они настраивают устройства через интернет-соединение, чтобы абонентам не приходилось узнавать эту информацию у своего провайдера по телефону. Чаще всего с помощью

DHCP передается маска сети, IP-адрес шлюза по умолчанию, а также IP-адреса DNS и серверов времени. DHCP во многом заменил своих предшественников (RARP и BOOTP), функциональность которых оставляла желать лучшего.

5.6.5. Коммутация меток и MPLS

До сих пор, путешествуя по сетевому уровню Интернета, мы говорили в основном о пакетах и дейтаграммах, передаваемых IP-маршрутизаторами. Сейчас все более популярной (особенно у провайдеров) становится еще одна технология, позволяющая передавать интернет-трафик по сети. Она называется MPLS (Multiprotocol Label Switching — мультипротокольная коммутация меток) и находится в опасной близости к коммутации каналов. Хотя многие члены интернет-сообщества испытывают неприязнь к сетям, ориентированным на соединение, похоже, что эта идея снова становится популярной. Как однажды сказал Йоги Берра, и снова это дежавю. Но в том, как маршруты создаются в Интернете и в сетях, ориентированных на соединение, есть существенная разница. Так что этот метод — не то же самое, что коммутация каналов.

MPLS присваивает пакету специальную метку, и пересылка производится не по адресу, а по этой метке. Если добавлять метки во внутреннюю таблицу, выбор выходного канала будет соответствовать поиску в этой таблице. Это существенно ускоряет пересылку. Эта идея легла в основу MPLS, которая изначально разрабатывалась как патентованная технология, известная под разными именами — например, коммутация меток (tag switching). В конечном счете, проблемная группа IETF занялась стандартизацией идей. Стандарт описан в документе RFC 3031 и многих других. Главными преимуществами, проверенными временем, являются гибкая маршрутизация и быстрая передача пакетов, позволяющая обеспечить необходимое качество обслуживания.

Первая проблема состоит вот в чем: куда поставить метку? Поскольку IP-пакеты не предназначены для виртуальных каналов, в их заголовке не предусмотрено место для номеров виртуальных каналов. Следовательно, нужно добавлять новый заголовок MPLS в начало IP-пакета. На линии между маршрутизаторами, используется протокол, включающий заголовки PPP, MPLS, IP и TCP, как показано на рис. 5.53.

Рис. 5.53. Передача TCP-сегмента с использованием IP, MPLS и PPP

Обычно в заголовок MPLS входит четыре поля, наиболее важное из которых — поле Метка, значением которой является индекс. Поле Качество обслуживания указывает на применяемый класс обслуживания. Поле S связано со стеком меток (речь об этом пойдет ниже). Поле Время жизни показывает, сколько еще раз пакет может быть отправлен. Его значение уменьшается на каждом маршрутизаторе; если оно равно 0, пакет игнорируется. Благодаря этому исключаются бесконечные циклы в случае сбоя маршрутизации.

MPLS располагается между протоколом сетевого уровня IP и протоколом канального уровня PPP. Этот уровень нельзя назвать третьим, так как метки задаются на основе IP-адреса или другого адреса сетевого уровня. Но это и не второй уровень, хотя бы потому, что MPLS контролирует передачу пакета на нескольких транзитных участках, а не на одном. Поэтому иногда этот протокол называют протоколом уровня 2.5. Это яркий пример того, что реальные протоколы не всегда вписываются в нашу идеальную уровневую модель.

Так как заголовки MPLS не являются частью пакетов сетевого уровня и также не имеют отношения к кадрам канального уровня, MPLS является методом, не зависящим от обоих этих уровней. Кроме всего прочего, это свойство означает, что можно создать такие коммутаторы MPLS, которые могут пересылать как IP-пакеты, так и не-^-пакеты, в зависимости от того, что необходимо в каждом конкретном случае. Именно отсюда следует «мультипротокольность» метода, отраженная в его названии. MPLS может также передавать IP-пакеты через не-№-сети.

Когда пакет, расширенный за счет заголовка MPLS, прибывает на маршрутизатор коммутации меток (LSR, Label Switched Router) извлеченная из него метка используется в качестве индекса таблицы, по которой определяется исходящая линия и значение новой метки. Смена меток используется во всех сетях с виртуальными каналами. Метки имеют только локальное значение, и два разных маршрутизатора могут снабдить независимые пакеты одной и той же меткой, если их нужно направить на одну и ту же линию третьего маршрутизатора. Поэтому, чтобы метки можно было различить на приемном конце, их приходится менять при каждом переходе. Мы видели этот механизм в действии — он был графически изображен на рис. 5.3. В MPLS используется такой же метод.

Вообще-то, иногда различают передачу (forwarding) и коммутацию (switching). Передача — это процесс нахождения адреса, наиболее совпадающего с адресом назначения, в таблице маршрутизации, чтобы решить, куда отправлять пакет. Примером IP-передачи является алгоритм поиска наиболее длинного совпадающего префикса. При коммутации в таблице маршрутизации производится поиск по меткам, извлеченным из пакета. Это проще и быстрее. Правда, такие определения не очень-то универсальны.

Так как большинство хостов и маршрутизаторов не понимают MPLS, мы могли бы задаться вопросом, как и когда метки прикрепляются к пакетам. Это происходит в тот момент, когда пакет достигает границы MPLS-сети. Пограничный маршрутизатор (LER, Label Edge Router) проверяет IP-адрес назначения и другие поля, определяя, по какому MPLS-пути должен пойти пакет, и присваивает пакету соответствующую метку. По ней пакет передается в сети MPLS. На другой границе MPLS-сети метка уже не нужна, и она удаляется, после чего IP-пакет становится открытым для другой сети. Этот процесс показан на рис. 5.54. Одним из отличий от традиционных виртуальных каналов является уровень агрегации. Конечно, можно каждому потоку, проходящему через MPLS-сеть, предоставить собственный набор меток. Однако более распространенным приемом является группировка потоков, заканчивающихся на данном маршрутизаторе или в данной ЛВС, и использование одной метки для всех таких потоков. О потоках, сгруппированных вместе и имеющих одинаковые метки, говорят, что они принадлежат одному классу эквивалентности пересылок (FEC Forwarding

Equivalence Class). В такой класс входят пакеты, не только идущие по одному и тому же маршруту, но и обслуживаемые по одному классу (в терминах дифференцированного обслуживания). Такие пакеты воспринимаются при пересылке одинаково.

Рис. 5.54. Передача IP-пакета через MPLS-сеть

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

На самом деле MPLS идет дальше. Этот протокол может работать одновременно на нескольких уровнях, используя несколько меток. Представьте себе несколько пакетов с разными метками (например, если сеть должна по-разному их обрабатывать), которые должны пройти один и тот же путь до определенного адреса. В таком случае мы можем задать для всех пакетов один путь. Когда пакеты, уже имеющие метку, попадают на начало пути, в начало записывается новая метка. Это называется стеком меток. Самая наружная метка служит проводником пакета по пути. В конце пути она удаляется, и оставшиеся метки (если они есть) ведут пакет дальше. Бит S (см. рис. 5.53) позволяет маршрутизатору, удаляющему метку, узнать, остались ли у пакета еще метки. Единичное значение бита говорит о том, что метка — последняя в стеке, а нулевое значение говорит об обратном.

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

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

Имеется несколько вариантов этого подхода. Один из них работает следующим образом. При загрузке маршрутизатора выявляется, для каких маршрутов он является пунктом назначения (например, какие префиксы принадлежат его интерфейсам). Для них создается один или несколько FEC, каждому из них выделяется метка, значение которой сообщается соседям. Соседи, в свою очередь, заносят эти метки в свои таблицы пересылки и посылают новые метки своим соседям. Процесс продолжается до тех пор, пока все маршрутизаторы не получат представление о маршрутах. По мере формирования путей могут резервироваться ресурсы, что позволяет обеспечить надлежащее качество обслуживания. В других вариантах устанавливаются другие пути (например, пути управления трафиком, учитывающие неиспользуемую пропускную способность) или создаются пути «по требованию», предоставляющие нужный уровень обслуживания.

Хотя основные идеи MPLS довольно просты, детали этого метода чрезвычайно сложны, причем существует множество вариаций, находящихся в стадии активной разработки. Дополнительную информацию можно найти в книгах (Davie и Farrel, 2008; Davie и Rekhter, 2000).

5.6.6. Протокол внутреннего шлюза OSPF

Итак, мы завершили изучение процесса передачи пакетов в Интернете. Пришло время перейти к новой теме — маршрутизации в Интернете. Как уже упоминалось, Интернет состоит из большого количества независимых сетей или автономных систем (АС), которыми управляют различные организации — компании, университеты, провайдеры. Каждая автономная система может использовать собственный внутренний, или внутридоменный, алгоритм маршрутизации (intradomain routing). Тем не менее более-менее распространенных стандартных протоколов совсем немного. В данном разделе будет рассмотрена внутридоменная маршрутизация и популярный протокол OSPF. Алгоритм маршрутизации внутри автономной системы называется протоколом внутреннего шлюза (interior gateway protocol). В следующем разделе мы обсудим вопрос маршрутизации между независимыми сетями, или междоменной маршрутизации (interdomain routing). В данном случае все сети должны использовать один и тот же алгоритм маршрутизации или протокол внешнего шлюза (exterior gateway protocol). В Интернете используется протокол BGP (Border Gateway Protocol — пограничный межсетевой протокол).

Изначально в качестве протокола внутридоменной маршрутизации использовалась схема маршрутизации по вектору расстояний, основанная на распределенном алгоритме Беллмана—Форда (Bellman—Ford) и унаследованная из ARPANET. В первую очередь это RIP (Routing Information Protocol — протокол маршрутной информации), использующийся до сих пор. Он хорошо работал в небольших системах, но по мере увеличения автономных систем стали проявляться его недостатки, такие как проблема счета до бесконечности и медленная сходимость, поэтому в мае 1979 года он был заменен протоколом состояния каналов. В 1988 году проблемная группа проектирования Интернета (IETF, Internet Engineering Task Force) начала работу над протоколом, учитывающим состояние линий, для внутридоменной маршрутизации. Этот протокол под названием OSPF (Open Shortest Path First открытый алгоритм предпочтительного выбора кратчайшего маршрута) был признан стандартом в 1990 году. Идея была заимствована из протокола IS-IS (Intermediate System to Intermediate System — связь между промежуточными системами), ставшего стандартом ISO. Эти два протокола скорее похожи, чем различны. Более подробное описание см. в RFC 2328. Они являются основными протоколами внутридоменной маршрутизации и в настоящее время поддерживаются многочисленными производителями маршрутизаторов. OSPF чаще используется в корпоративных сетях, IS-IS — в сетях интернет-провайдеров. Ниже будет дано краткое описание работы протокола OSPF.

Учитывая большой опыт работы с различными алгоритмами, группа разработчиков согласовывала свои действия с длинным списком требований, которые необходимо было удовлетворить. Во-первых, этот алгоритм должен публиковаться в открытой литературе, откуда буква «О» (Open — открытый) в OSPF. Из этого следовало, что патентованный алгоритм, принадлежащий одной компании, не годится. Во-вторых, новый протокол должен был уметь учитывать широкий спектр различных параметров, включая физическое расстояние, задержку и т. д. В-третьих, этот алгоритм должен был быть динамическим, а также автоматически и быстро адаптирующимся к изменениям топологии.

В-четвертых (это требование впервые было предъявлено именно к OSPF), он должен был поддерживать выбор маршрутов, основываясь на типе сервиса. Новый протокол должен был уметь по-разному выбирать маршрут для трафика реального времени и для других видов трафика. В то время IP-пакет содержал поле Тип сервиса, но ни один из имевшихся протоколов маршрутизации не использовал его. Это поле было и в OSPF, но и здесь никто его не использовал. Поэтому в результате его убрали. Возможно, это требование опередило свое время, так как было выдвинуто до появления дифференцированного обслуживания, вернувшего к жизни классы обслуживания.

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

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

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

Протокол OSPF поддерживает двухточечные линии (например, SONET) и широковещательные сети (большинство ЛВС). Он также поддерживает сети с множественными маршрутизаторами, каждый из которых может напрямую соединяться с любым другим (сети множественного доступа — multi-access networks), даже если в них невозможно широковещание. Предыдущие протоколы не так хорошо справлялись с этой проблемой.

На рис. 5.55, а показан пример автономной системы. Здесь не указаны хосты, так как обычно они не играют большой роли в OSPF; маршрутизаторы и сети (которые могут содержать хосты) гораздо более важны. Большинство маршрутизаторов соединено с другими маршрутизаторами двухточечными линиями, а также с сетями, к хостам которых им необходим доступ. Но R3, R4 и R5 соединены широковещательной ЛВС, например коммутируемой сетью Ethernet.

Рис. 5.55. Сеть множественного доступа: а — автономная система; б — представление (а)

в виде графа

В основе работы протокола OSPF лежит обобщенное представление о множестве сетей, маршрутизаторов и связей в виде направленного графа, в котором каждой дуге поставлена в соответствие ее цена (может выражаться в таких физических параметрах, как расстояние, задержка и т. д.). Двухточечное соединение между двумя маршрутизаторами представляется в виде пары дуг, по одной в каждом направлении. Их весовые коэффициенты могут быть различными. Широковещательная сеть представляется в виде узла для самой сети, а также в виде узла для каждого маршрутизатора. Дуги, идущие от сетевого узла к узлам маршрутизаторов, обладают нулевым весом. Но они все равно важны, так как без них не будет существовать путь через сеть. Другие сети, состоящие исключительно из хостов, имеют только дуги, направленные к ним, и не имеют обратных дуг. То есть маршруты к хостам возможны, а через них — нет.

На рис. 5.55, б сеть, изображенная на рис. 5.55, а, представлена в виде графа. По сути, как раз это и делает OSPF. Когда представление в виде графа получено, маршрутизаторы могут вычислить кратчайшие пути до всех остальных узлов с помощью метода, учитывающего состояние линий. Возможно, что некоторые пути будут одинаково короткими. Тогда OSPF запоминает оба пути и использует эту информацию для разделения трафика. Это помогает распределить нагрузку более равномерно и называется ECMP (Equal Cost MultiPath использование множества равноценных маршрутов).

Многие автономные системы в Интернете сами по себе довольно велики и управлять ими непросто. Поэтому протокол OSPF позволяет делить их на пронумерованные области, то есть на сети или множества смежных сетей. Области не должны перекрываться, но не обязаны быть исчерпывающими, то есть некоторые маршрутизаторы могут не принадлежать ни одной области. Если маршрутизатор полностью принадлежит какой-то области, он называется внутренним маршрутизатором (internal router). Область является обобщением отдельной сети. За пределами области видны ее адреса, но не ее топология. Это упрощает масштабирование процесса маршрутизации.

У каждой автономной системы есть магистральная область (backbone area), называемая областью 0. Маршрутизаторы, расположенные в этой области, называются магистральными маршрутизаторами (backbone routers). Все области соединены с магистралью, например, туннелями, так что по магистрали можно попасть из любой области автономной системы в ее любую другую область. Туннель представляется на графе в виде дуги и обладает определенной ценой. Как и в случае других областей, топология магистрали за ее пределами не видна.

Маршрутизатор, соединенный одновременно с двумя и более областями, называется пограничным маршрутизатором области (area border router). Он также должен быть частью магистрали. Его задача — собирать сведения об адресах одной области и передавать их другим областям. Эти сведения включают стоимость передачи, но не всю информацию о топологии области. Зная стоимость передачи, хосты других областей могут выбрать тот маршрутизатор границы области, через который они войдут в эту область. Отсутствие информации о топологии уменьшает трафик и упрощает процесс вычисления кратчайших путей для маршрутизаторов, находящихся вне данной области. Но если вне области есть только один пограничный маршрутизатор области, эти сведения передавать бессмысленно. Все пути, ведущие за пределы области, начинаются с указания: «Идите на пограничный маршрутизатор». Такая область называется тупиковой областью (stub area).

Последний тип маршрутизаторов — пограничные маршрутизаторы автономной системы (AS boundary router). Они передают внутрь области сведения о путях к внешним адресам на другие АС. Внешние пути становятся адресами, до которых можно добраться через пограничный маршрутизатор автономной системы; при этом указывается стоимость передачи. Внешний путь может быть передан на один или более таких маршрутизаторов. Связь между автономными системами, областями и различными типами маршрутизаторов показана на рис. 5.56. Один маршрутизатор может играть несколько ролей — например, быть и пограничным маршрутизатором области, и магистральным маршрутизатором.

Рис. 5.56. Взаимосвязь между автономными системами, магистралями и областями в OSPF

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

Для отправителя и получателя из одной области выбирается наилучший внутриобластной маршрут (полностью лежащий в этой области). Для отправителя и получателя из разных областей межобластной маршрут проходит от источника к магистрали, затем по магистрали к области назначения, а затем уже к адресу назначения. Такой алгоритм приводит к конфигурации типа «звезда», в которой магистраль исполняет роль концентратора, а области являются лучами звезды. Так как при выборе маршрута учитывается его стоимость, разные маршрутизаторы могут попадать на магистраль через разные пограничные маршрутизаторы области. Пакеты направляются от отправителя к получателю в натуральном виде. Они не упаковываются в другие пакеты и не туннелируются, кроме случаев, когда они направляются в области, с которыми магистраль соединена по туннелю. Кроме того, пути к внешним адресам могут включать внешнюю стоимость (от пограничного маршрутизатора по внешнему пути) или только внутреннюю (в пределах АС).

При загрузке маршрутизатор рассылает сообщения ПРИВЕТСТВИЕ (HELLO) по всем своим двухточечным линиям, производя многоадресную рассылку по локальным сетям для групп, состоящих из всех остальных маршрутизаторов. С помощью получаемых ответов каждый маршрутизатор знакомится со своими соседями. Все маршрутизаторы одной ЛВС являются соседями.

Протокол OSPF работает при помощи обмена информацией между смежными маршрутизаторами, что не то же самое, что соседние маршрутизаторы. В частности, общение каждого маршрутизатора с каждым маршрутизатором локальной сети неэффективно. Поэтому один маршрутизатор выбирается назначенным маршрутизатором (designated router DR). Он считается смежным (adjacent) со всеми остальными маршрутизаторами данной ЛВС и обменивается с ними информацией. Соседние маршрутизаторы, не являющиеся смежными, не обмениваются информацией друг с другом. На случай выхода из строя основного назначенного маршрутизатора всегда поддерживается в готовом состоянии запасной назначенный маршрутизатор (backup designated router BDR).

При нормальной работе каждый маршрутизатор периодически рассылает методом заливки сообщение ОБНОВЛЕНИЕ СОСТОЯНИЯ КАНАЛОВ (LINK STATE UPDATE) всем своим смежным маршрутизаторам. Это сообщение содержит сведения о состоянии маршрутизатора и предоставляет информацию о цене, используемую в базах данных. В ответ на эти сообщения посылаются подтверждения, что повышает их надежность. Каждое сообщение получает последовательный номер, так что маршрутизатор может распознать, что новее: пришедшее сообщение или сообщение, хранимое им. Маршрутизаторы также рассылают эти сообщения, когда включается или выключается канал или изменяется его цена.

Сообщение ОПИСАНИЕ БАЗЫ ДАННЫХ (DATABASE DESCRIPTION) содержит порядковые номера всех записей о состоянии линий, которыми владеет отправитель. Сравнивая соб

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

Каждый маршрутизатор может запросить информацию о состоянии линий у своего партнера с помощью сообщения ЗАПРОС О СОСТОЯНИИ КАНАЛА (LINK STATE REQUEST). В результате каждая пара смежных маршрутизаторов выясняет, чьи сведения являются более свежими, и, таким образом, по области распространяется наиболее новая информация. Все эти сообщения посылаются в виде IP-пакетов. Пять типов сообщений приведены в табл. 5.9.

Таблица 5.9. Пять типов сообщений протокола OSPF

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

5.6.7. Протокол внешнего шлюза BGP

В пределах одной автономной системы наиболее часто используются протоколы OSPF и IS-IS. При выборе маршрута между различными автономными системами используется другой протокол, BGP (Border Gateway Protocol пограничный межсетевой протокол). Для выбора маршрута между различными автономными системами действительно требуется другой протокол, так как цели внутридоменного и междоменого протоколов различны. Задача внутридоменного протокола ограничивается максимально эффективной передачей пакетов от отправителя к получателю. Политикой этот протокол не интересуется.

Междоменный протокол, напротив, вынужден заниматься политикой (Metz, 2001). Например, корпоративной автономной системе может понадобиться возможность

принимать и посылать пакеты на любой сайт Интернета. Однако прохождение через автономную систему пакета, отправитель и получатель которого находятся за пределами данного государства, может быть нежелательно, даже если кратчайший путь между отправителем и получателем пролегает через эту автономную систему («Это их заботы, а не наши»). С другой стороны, может оказаться желательным транзит трафика для других автономных систем, возможно, соседних, которые специально заплатили за эту услугу. Например, телефонные компании были бы рады оказывать подобные услуги, но только своим клиентам. Протоколы внешнего шлюза вообще и протокол BGP в частности разрабатывались для возможности учета различных стратегий при выборе маршрута между автономными системами.

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

1.    Не передавать коммерческий трафик в образовательные сети.

2.    Никогда не прокладывать через Ирак маршрут, начинающийся в Пентагоне.

3.    Использовать TeliaSonera вместо Verizon, так как она дешевле.

4.    Не использовать AT&T в Австралии, так как производительность будет низкой.

5.    Трафик, начинающийся или заканчивающийся в Apple, не должен проходить через

Google.

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

Реализация политики маршрутизации заключается в том, чтобы решить, какой трафик может перемещаться по каким каналам, соединяющим автономные системы. Один из довольно популярных вариантов выглядит так: провайдер-клиент платит другому провайдеру за отправку пакетов на любой адрес в сети Интернет и получение пакетов с любого адреса. В таком случае говорят, что провайдер-клиент покупает у другого провайдера транзитные услуги. Эта ситуация аналогична тому, как обычный пользователь домашней сети покупает у провайдера услугу доступа к Интернету. Чтобы это работало, провайдер должен объявить абоненту маршруты на все адреса в сети Интернет по каналу, который их соединяет. Тогда абонент будет знать маршрут, по которому можно отправить пакет куда угодно. И наоборот, абонент должен объявить провайдеру маршруты на все адреса в пределах своей сети. Тогда провайдер сможет передавать трафик только на эти адреса — абоненту не нужен трафик, предназначенный для кого-то другого.

Пример предоставления транзитных услуг приведен на рис. 5.57. Перед нами четыре автономные системы, соединенные между собой. Соединение часто осуществляется через точку обмена интернет-трафиком (IXP, Internet eXchange Point),

инфраструктуру, с которой соединяются многие интернет-провайдеры, чтобы получить доступ к другим интернет-провайдерам. AS2, AS3 и AS4 — клиенты AS1. Они покупают у AS1 транзитные услуги. Таким образом, пакет, отправленный источником A на C, передается из AS2 в AS1. а затем в AS4. Объявления о маршрутах перемещаются в противоположном направлении. Чтобы источник мог передать пакет C через AS1,

AS4 объявляет C в качестве адреса назначения своему провайдеру (AS1). После этого AS1 объявляет маршрут до C другим своим клиентам, включая AS2, чтобы они могли отправлять трафик на C через AS1.

Рис. 5.57. Политика маршрутизации между четырьмя автономными системами

На рис. 5.57 все остальные АС покупают транзитные услуги у AS1. Благодаря этому они могут связаться с любым хостом в сети Интернет. Но за эту возможность им приходится платить. Пусть AS2 и AS3 обмениваются большим количеством трафика. Если эти сети соединены, то они могут выбрать другую политику — передавать трафик напрямую и бесплатно. Это уменьшит количество трафика, передаваемого AS1 от их имени, и сократит их расходы. Такая политика называется пирингом (peering).

Для реализации пиринга две АС должны передавать друг другу объявления о маршрутах для своих адресов. Это позволяет AS2 отправлять пакеты AS3 из A в B, и наоборот. Однако следует обратить внимание на то, что пиринг не транзитивен. На рис. 5.57 сети AS3 и AS4 тоже используют политику пиринга, и поэтому пакеты из C в B моут передаваться напрямую в AS4. Но что если пакет нужно отправить из C в A? AS3 объявляет AS4 маршрут до B, но не объявляет маршрута до A. Поэтому трафик не сможет пройти из AS4 в AS3, а затем в AS2, хотя физический путь существует. Но именно это и выгодно AS3. Она хочет обмениваться трафиком с AS4, но не хочет, чтобы AS4 передавала через нее трафик для остального Интернета. Вместо этого AS4 придется пользоваться транзитными услугами AS1, которая, кстати, и передаст пакет из C в A.

Теперь, когда мы знаем о транзитных услугах и пиринге, посмотрим на транзитные соглашения A, B и C. К примеру, A покупает доступ к Интернету у AS2. Сеть A может состоять из одного компьютера, а может быть сетью компании с множеством ЛВС. Но в любом случае A не нужно использовать BGP, так как она является тупиковой сетью (stub network), соединенной с остальным Интернетом только одной линией. Отправлять пакеты за пределы сети можно только через эту единственную линию. Такой путь можно задать в качестве пути по умолчанию. Именно поэтому A, B и C на рисунке не представлены в виде автономных систем с внутридоменной маршрутизацией.

С другой стороны, некоторые сети компаний подключены к нескольким интернет-провайдерам. Это делается с целью повышения надежности, так как при отказе одного из провайдеров трафик может быть передан через другого провайдера. Этот метод называется многолинейным подключением (multihoming). В таком случае компания, скорее всего, будет использовать протокол междоменной маршрутизации (например, BGP), чтобы АС знали, через какого провайдера следует передавать трафик.

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

BGP по сути является вариантом протокола маршрутизации по вектору расстояний, однако он значительно отличается от других подобных протоколов, например протокола RIP (Routing Information Protocol — протокол маршрутной информации).

Как мы уже видели, вместо минимального расстояния при выборе маршрута учитывается политика. Еще одно отличие состоит в том, что вместо того чтобы периодически сообщать всем своим соседям свои расчеты цены передачи до каждого возможного адресата, каждый BGP-маршрутизатор передает соседям точную информацию об используемых им маршрутах. Этот подход называется протоколом векторов маршрутов (Path Vector Protocol). Путь состоит из следующего маршрутизатора (совсем не обязательно смежного: он может находиться в другой части сети провайдера) и последовательности АС, или пути АС (AS path), через которые проходит маршрут (в обратном порядке). Пары BGP-маршрутизаторов общаются друг с другом, устанавливая TCP-соединения. Таким образом обеспечивается надежная связь и скрываются детали устройства сети, по которой проходит трафик.

На рис. 5.58 показан пример того, как маршрутизаторы обмениваются объявлениями о маршрутах. Здесь мы видим три автономных сети, причем средняя предоставляет транзитные услуги правому и левому интернет-провайдеру. Объявление о маршруте к префиксу C начинается на AS3. Когда оно доходит до R2c (вверху), оно состоит из AS3 и следующего маршрутизатора R3a. Внизу этот маршрут имеет тот же путь АС, но другой следующий маршрутизатор, так как он пришел по другому каналу. Это объявление распространяется дальше и пересекает границу AS1. На маршрутизаторе R1a (вверху) путь АС состоит из AS2 и AS3, а следующий маршрутизатор — R2a.

Рис. 5.58. Распространение объявлений о BGP-маршруте

Хранение полного пути для маршрута упрощает обнаружение и устранение циклов. Правило выглядит так: каждый маршрутизатор, отправляющий маршрут за пределы своей АС, добавляет в начало маршрута номер своей АС. (Именно поэтому список имеет обратный порядок.) Когда маршрутизатор получает маршрут, он проверяет, есть ли в пути АС номер его собственной АС. Положительный ответ означает, что в маршруте есть цикл; в таком случае объявление отвергается. Но несмотря на такие меры предосторожности, в конце 1990-х было обнаружено, что BGP все же сталкивается с одним из вариантов проблемы счета до бесконечности (Labovitz и др., 2001). Хотя от долговременных циклов удается избавиться, из-за медленной конвергенции маршрутизаторов могут возникать временные циклы.

Задавать путь списком АС — довольно-таки грубый вариант. АС может быть как небольшой компанией, так и международной магистральной сетью. По маршруту этого узнать невозможно. А BGP даже не пытается этого сделать, так как в разных АС могут использоваться разные внутридоменые протоколы, вследствие чего стоимость передачи трафика невозможно сравнить. Но если бы их можно было сравнить, с большой вероятностью возникла бы другая проблема: часто АС скрывают данные о своих внутренних параметрах. Это одно из основных отличий междоменной маршрутизации от внутридоменной.

До сих пор мы говорили о том, как объявление маршрута передается по каналу между двумя интернет-провайдерами. Но нужно также уметь отправлять BGP-маршруты в другие части сети провайдера, чтобы оттуда они могли быть переданы другим провайдерам. Эту задачу должен решать внутридоменный протокол. Но поскольку BGP очень хорошо работает в крупных сетях, для этого часто используется его вариант. Он называется внутренним BGP (iBGP — internal BGP), в противоположность обычному, или внешнему BGP (eBGP — external BGP).

Правило распространения маршрутов внутри сети провайдера выглядит так: маршрутизатор, расположенный на границе сети, узнает обо всех маршрутах, о которых знают другие пограничные маршрутизаторы (в целях согласованности их действий). Если какому-то пограничному маршрутизатору становится известен префикс к IP 128.208.0.0/16, все другие маршрутизаторы тоже о нем узнают. Тогда до этого префикса можно будет добраться из любой точки сети провайдера, причем не важно, как пакет попал в эту сеть.

Во избежание беспорядка этот процесс не показан на рис. 5.58. Но в качестве примера можно привести такой вариант: маршрутизатор R2b узнает, что он может добраться до C либо через R2c (вверху), либо через R2d (внизу). Данные о следующем маршрутизаторе будут обновляться, пока маршрут будет перемещаться по сети провайдера. Благодаря этому маршрутизаторы на разных концах сети будут знать, через какой маршрутизатор можно выйти за пределы сети на другом ее конце. Если посмотреть на самые левые маршруты, то можно увидеть, что для них следующий маршрутизатор находится в той же сети, а не в соседней.

Теперь мы можем перейти к обсуждению важного вопроса: как BGP-маршрутизаторы выбирают маршрут до данного адреса? Каждый BGP-маршрутизатор узнает маршрут до данного адреса от соединенного с ним маршрутизатора в соседней сети провайдера, а также от других пограничных маршрутизаторов (которые узнают другие возможные маршруты от своего соседнего маршрутизатора). Далее каждый маршрутизатор решает, какой из этих маршрутов лучше всего использовать. В конечном итоге получается, что политику выбора маршрута определяет интернет-провайдер. Однако такое объяснение является слишком общим и не вполне удовлетворительным, так что давайте поговорим о нескольких возможных стратегиях.

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

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

Наконец, существует стратегия, согласно которой предпочтение отдается маршруту с наименьшей стоимостью в пределах сети провайдера. Пример ее реализации показан на рис. 5.58. Пакеты из A в C покидают AS1 через верхний маршрутизатор R1a. Пакет из B выходит через нижний маршрутизатор R1b. Так происходит потому, что A и B выбирают наименее затратный способ выхода из AS1. А поскольку они расположены в разных частях сети провайдера, наилучшие пути для них различаются. То же самое происходит, когда пакеты проходят через AS2. На последнем участке AS3 должна переправить пакет из B по своей сети.

Эта стратегия называется ранним выходом или методом «горячей картошки» (hot-potato routing). Интересно, что при такой маршрутизации пути обычно бывают несимметричными. Рассмотрим маршрут пакета, переданного из C в B. Пакет сразу же выйдет из AS3 через верхний маршрутизатор. При переходе из AS2 в AS1 он останется наверху, а уже потом будет долго путешествовать внутри AS1. Это зеркальное отражение пути от B к C.

Из всего этого следует, что каждый BGP-маршрутизатор выбирает свой наилучший путь из нескольких возможных. Но вопреки первоначальным ожиданиям, нельзя сказать, что BGP отвечает за маршруты между разными АС, а OSPF — за маршруты внутри одной АС. BGP и протокол внутреннего шлюза связаны более сложным образом. В частности, это значит, что BGP может найти наилучшую точку выхода за пределы сети провайдера и выбор точки будет различаться для разных уголков сети, как в случае стратегии «горячей картошки». Также это значит, что BGP-маршрутизаторы из разных частей одной АС могут использовать разные пути АС до одного и того же места назначения. При этом провайдер должен позаботиться о том, чтобы при такой свободе выбора маршруты были совместимы, но это уже относится к практике.

Как это ни удивительно, мы лишь слегка коснулись вопроса использования BGP. Для более подробной информации см. спецификацию BGP версии 4 в RFC 4271 и другие RFC. Но помните, что большинство трудностей касаются политики маршрутизации, о которой не говорится в спецификации протокола BGP.

5.6.8. Многоадресная рассылка в Интернете

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

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

Диапазон IP-адресов 224.0.0.0/24 зарезервирован для многоадресной рассылки в локальной сети. В таком случае протокол маршрутизации не требуется. Пакеты передаются всей ЛВС с помощью широковещания с указанием группового адреса. Все хосты в этой сети получают пакет, но обрабатывают его только члены группы. За пределы ЛВС пакет не передается. Вот некоторые примеры групповых адресов:

♦    224.0.0.1 — все системы локальной сети;

♦    224.0.0.2 — все маршрутизаторы локальной сети;

♦    224.0.0.5 — все OSPF-маршрутизаторы локальной сети;

♦    224.0.0.251 — все DNS-серверы локальной сети.

В других случаях члены группы могут располагаться в разных сетях. Тогда протокол маршрутизации необходим. Но для начала маршрутизаторы, передающие многоадресные сообщения, должны знать, какие хосты являются членами группы. Процесс может попросить свой хост присоединиться к какой-либо группе или покинуть группу. Каждый хост следит за тем, членами каких групп являются его процессы в текущий момент. Когда последний процесс хоста покидает группу, хост больше не является членом этой группы. Примерно раз в минуту каждый многоадресный маршрутизатор совершает аппаратную (то есть на уровне передачи данных) многоадресную рассылку хостам на своей локальной сети (по адресу 224.0.0.1) с просьбой сообщить о группах, к которым в данный момент принадлежат их процессы. Многоадресные маршрутизаторы не обязательно должны находиться там же, где обычные маршрутизаторы. Каждый хост посылает обратно ответы для всех интересующих его адресов класса D. Эти пакеты запросов и ответов используются протоколом IGMP (Internet Group Management Protocol — протокол управления группами в Интернете). Он описан в RFC 3376.

Для построения связующего дерева, позволяющего получить пути от отправителей до всех членов группы, используются различные протоколы многоадресной маршрутизации. О соответствующих алгоритмах мы уже говорили в разделе 5.2.8. Внутри автономной системы чаще всего используется протокольно-независимая многоадресная рассылка (PIM, Protocol Independent Multicast). Существует несколько вариантов PIM. При PIM в плотном режиме (Dense Mode PIM) создается усеченное дерево, построенное методом продвижения по встречному пути. Такой вариант подходит в ситуациях, когда члены группы находятся во всех частях сети — например, при распространении файлов на множественные серверы. При PIM в разреженном режиме (Sparse Mode PIM) создаются связующие деревья, похожие на деревья с основанием в ядре. Такой вариант может использоваться, к примеру, когда поставщик контента транслирует ТВ-сигнал абонентам своей IP-сети. Вариант этой схемы под названием Source-Specific Multicast PIM работает лучше в ситуациях с одним источником. Наконец, если члены группы находятся в нескольких АС, для создания многоадресных маршрутов необходимо использовать специальные расширения BGP или туннелирование.

5.6.9. Мобильный IP

Многие пользователи Интернета обладают портативными компьютерами и заинтересованы в возможности оставаться в подключенном к сети состоянии, даже находясь в пути. К сожалению, система адресации IP такова, что реализовать это оказывается гораздо сложнее, чем кажется (вскоре мы поговорим об этом подробнее). Когда потребность в мобильных хостах значительно возросла, проблемная группа проектирования Интернета (IETF, Internet Engineering Task Force) создала рабочую группу для поиска решения проблемы. Созданная рабочая группа быстро сформулировала набор целей, которых хотелось бы достичь, независимо от способа решения. Основными целями были признаны следующие.

1.    Каждый мобильный хост должен иметь возможность использовать свой домашний IP-адрес где угодно.

2.    Изменения программного обеспечения фиксированных хостов недопустимы.

3.    Изменения программного обеспечения и таблиц маршрутизаторов недопустимы.

4.    Большая часть пакетов, направляемых мобильным хостам, должны доставляться напрямую.

5.    Не должно быть никаких дополнительных расходов, когда мобильный хост находится дома.

Рабочая группа выработала решение, описанное в разделе 5.2.10. Суть его, напомним, заключалась в том, что везде, где требуется предоставить возможность перемещения в пространстве, следует создать внутреннего агента (home agent). Когда мобильный хост прибывает на новое место, он получает новый IP-адрес (также называемый адресом для передачи). После этого мобильный хост сообщает внутреннему агенту о своем местоположении с помощью адреса для передачи. Если в момент прибытия пакета, предназначенного этому хосту, в домашнюю сеть хост находится в другом месте, внешний агент туннелирует этот пакет на хост, используя адрес для передачи. Мобильный хост может посылать ответные пакеты, но при этом адресом отправителя будет домашний адрес. Это решение удовлетворяет всем перечисленным выше требованиям за исключением рециркулирующих пакетов мобильных хостов.

Чтобы получить адрес для передачи в новой сети, мобильный хост может использовать DHCP. Или же, если IP-адресов не хватает, этот хост может отправлять и получать пакеты через внешнего агента, у которого уже есть IP-адрес в этой сети. Чтобы найти внешнего агента, хост использует тот же ICMP-механизм, что и при поиске внутреннего агента. После того как хост получил IP-адрес или нашел внешнего агента, он может по сети сообщить внутреннему агенту о своем текущем местоположении.

Внутренний агент должен перехватывать пакеты, предназначенные для мобильного хоста, только при отсутствии этого хоста в домашней сети. Сделать это можно с помощью ARP. Чтобы отправить пакет на IP-хост по сети Ethernet, маршрутизатор должен знать Ethernet-адрес хоста. Обычно маршрутизатор отправляет ARP-сообщение, в котором спрашивает что-то вроде «какой Ethernet-адрес у 160.80.40.20?» Если мобильный хост находится в домашней сети, он отвечает на запрос, содержащий его IP-адрес, сообщением со своим Ethernet-адресом. Если он находится в другом месте, на этот запрос отвечает внутренний агент, сообщая свой Ethernet-адрес. В результате маршрутизатор отправляет пакеты для 160.80.40.20 домашнему агенту. Как вы, возможно, помните, это называется ARP-прокси.

Чтобы быстро обновлять таблицы отображения адресов при перемещении хоста туда и обратно, используется другой метод, называемый добровольным ARP-сообщением (gratuitous ARP). Суть в том, что мобильный хост или внутренний агент отправляет самому себе ARP-запрос для мобильного IP-адреса, который заставляет маршрутизатор заменить в своей таблице запись о хосте.

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

Как и в случае со многими интернет-протоколами, дьявол кроется в деталях, и особенно в тех мелочах, которые касаются совместимости с другими протоколами. Здесь есть две сложности. Во-первых, NAT-блоку необходим доступ к TCP-и UDP-заголовкам, расположенным после IP-заголовка. Изначальный вариант туннелирования для мобильных IP не использовал эти заголовки и поэтому не работал с NAT-блоками. Позже было принято решение изменить способ добавления заголовков, включив UDP-заголовок.

Вторая сложность состоит в том, что некоторые провайдеры проверяют, соответствует ли IP-адрес источника тому расположению, где, по мнению протокола маршрутизации, источник должен находиться. Этот процесс называется фильтрацией на входе (ingress filtering) и является мерой безопасности, позволяющей отвергать трафик, поступивший с сомнительного адреса, так как он может представлять угрозу. Однако если мобильный хост находится не в домашней сети, его пакеты будут приходить с IP-адреса другой сети и поэтому, скорее всего, будут отвергнуты. Чтобы обойти эту проблему, мобильный хост может туннелировать пакеты внутреннему агенту с помощью адреса для передачи. Пакеты, отправленные отсюда, не будут казаться подозрительными. Минус такой схемы в том, что такой путь является далеко не прямым.

Еще одним вопросом является безопасность. Когда внутренний агент получает просьбу пересылать все пакеты, приходящие на имя Натальи, на некий IP-адрес, он не должен подчиняться, пока не убедится, что источником этого запроса является Наталья, а не кто-то пытающийся выдать себя за Наталью. Для этого применяются протоколы криптографической аутентификации, которые будут рассматриваться в главе 8.

Протоколы мобильности для IPv6 основаны на IPv4. Приведенная выше схема сталкивается с проблемой треугольной маршрутизации, при которой пакеты вынуждены делать крюк, проходя через внутреннего агента. IPv6 использует оптимизацию маршрута, позволяющую установить прямые пути между мобильным хостом и другими IP-адресами после того, как первые пакеты прошли длинный путь. Мобильный IPv6 описан в RFC 3775.

В сети Интернет появляется еще один вид мобильности. В некоторых самолетах есть встроенная беспроводная сеть, с помощью которой пассажиры с переносными компьютерами могут подключаться к Интернету. В самолете есть маршрутизатор, подключенный к остальному Интернету по беспроводной связи. (А вы думали, через кабель?) Так что по сути это летающий маршрутизатор, то есть мобильной является вся сеть. Схемы, реализующие мобильность сетей, работают так, что переносные компьютеры не замечают, что самолет движется. Они думают, что это просто другая сеть. Некоторые компьютеры используют мобильный IP, чтобы сохранять связь с домашней сетью, и в таком случае мы имеем дело с двумя уровнями мобильности. Мобильность сети для IPv6 описана в RFC 3963.

5.7. Резюме

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

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

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

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

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

В Интернете существует большое разнообразие протоколов, относящихся к сетевому уровню. К ним относятся протокол дейтаграмм — IP и соответствующие управляющие протоколы — ICMP, ARP и DHCP. В некоторых сетях IP-пакеты передает ориентированный на соединение протокол MPLS. Один из основных протоколов маршрутизации, использующихся внутри сетей, — это OSPF. Между сетями для маршрутизации используется протокол BGP. Интернету перестает хватать IP-адресов, поэтому была разработана новая версия протокола IP, IPv6, которая в настоящее время внедряется, но происходит это чрезвычайно медленно.

Вопросы

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

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

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

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

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

6.    Рассмотрите подсеть на рис. 5.10, а. Используется алгоритм дистанционно-векторной маршрутизации. На маршрутизатор C только что поступили следующие векторы: от B: (5, 0, 8, 12, 6, 2); от D: (16, 12, 6, 0, 9, 10); от E: (7, 6, 3, 9, 0, 4). Измеренные задержки до B, D и составляют 6, 3 и 5 соответственно. Какой будет новая таблица маршрутизатора C? Укажите используемые выходные линии и ожидаемое время задержки.

7.    В сети, состоящей из 50 маршрутизаторов, значения стоимости записываются как 8-битовые номера, а маршрутизаторы обмениваются векторами дважды в секунду. Какая пропускная способность на каждой (дуплексной) линии съедается работой распределенного алгоритма маршрутизации? Предполагается, что каждый маршрутизатор соединен тремя линиями с другими маршрутизаторами.

8.    На рис. 5.11 логическое ИЛИ двух наборов ACF-битов равно 111 для каждого ряда. Является ли это просто случайностью или же это сохраняется во всех подсетях при любых условиях?

9. Какие размеры регионов и кластеров следует выбрать для минимизации таблиц маршрутизации при трехуровневой иерархической маршрутизации, если количество маршрутизаторов равно 4800? Рекомендуется начать с гипотезы о том, что решение в виде k кластеров по k регионов из k маршрутизаторов близко к оптимальному Это означает, что число примерно равно корню кубическому из 4800 (около 16). Методом проб и ошибок подберите все три параметра так, чтобы они были близки к 16.

10.    В тексте утверждалось, что когда мобильного хоста нет в его домашней сети, пакеты, посланные на адрес его домашней ЛВС, перехватываются внутренним агентом этой ЛВС. Как этот перехват осуществляет внутренний агент в IP-сети на основе локальной сети 802.3?

11.    Сколько широковещательных пакетов формируется маршрутизатором B на рис. 5.5 с помощью:

1)    пересылки в обратном направлении?

2)    входного дерева?

12.    Рассмотрите рис. 5.13, а. Допустим, добавляется одна новая линия между Fи G, но входное дерево, показанное на рис. 5.13, б, остается без изменений. Какие изменения нужно внести в рис. 5.13, в?

13.    Рассчитайте многоадресное связующее дерево для маршрутизатора C в подсети, показанной ниже, для группы, состоящей из маршрутизаторов A, B, C, D, E, F, I и K.

14.    Допустим, узел В на рис. 5.18 только что перезагрузился и не имеет никакой информации о маршрутизации в своих таблицах. Внезапно у него появляется необходимость в маршруте к узлу H. Он рассылает широковещательным способом наборы TTL на 1, 2, 3 и т. д. Сколько раундов потребуется на поиск пути?

15.    В качестве возможного механизма борьбы с перегрузкой в подсети, использующей виртуальные каналы, маршрутизатор может воздержаться от подтверждения полученного пакета, пока, во-первых, он знает, что его последняя передача по виртуальному каналу была получена успешно, и, во-вторых, у него есть свободный буфер. Для простоты предположим, что маршрутизаторы используют протокол с ожиданием и что у каждого виртуального канала есть один буфер, выделенный ему для каждого направления трафика. Передача пакета (данных или подтверждения) занимает Т с. Путь пакета проходит через n маршрутизаторов. С какой скоростью пакеты доставляются адресату? Предполагается, что ошибки очень редки, а связь между хостом и маршрутизатором почти не отнимает времени.

16.    Дейтаграммная подсеть позволяет маршрутизаторам при необходимости выбрасывать пакеты. Вероятность того, что маршрутизатор отвергнет пакет, равна р. Рассмотрите маршрут, проходящий от хоста к хосту через два маршрутизатора. Если любой из маршрутизаторов отвергнет пакет, у хоста-отправителя, в конце концов, истечет интервал ожидания, и он попытается переслать пакет еще раз. Если обе линии (хост-маршрутизатор и маршрутизатормаршрутизатор) считать за транзитные участки, то чему равно среднее число

1)    транзитных участков, преодолеваемых пакетом за одну передачу?

2)    передач для одного пакета?

3)    транзитных участков, необходимых для получения пакета?

17.    В чем состоит основная разница между методом ECN и методом RED?

18.    Сеть использует для формирования трафика схему маркерного ведра. Новый маркер помещается в ведро каждые 5 мкс. Каждый маркер подходит для короткого пакета размером 48 байт. Чему равна максимальная скорость передачи данных в сети (не считая битов заголовка)?

19.    Компьютер, подключенный к сети, скорость передачи в которой равна 6 Мбит/с, регулируется маркерным ведром. Маркерное ведро наполняется со скоростью 1 Мбит/с. Его начальная емкость составляет 8 Мбит. Как долго сможет передавать компьютер на полной скорости в 6 Мбит/с?

20.    Сеть на рис. 5.30 использует RSVP в деревьях групповой рассылки для хостов 1 и 2. Допустим, хост 3 запрашивает канал с пропускной способностью 2 Мбайт/с для потока от хоста 1 и еще один канал с пропускной способностью 1 Мбайт/с для потока от хоста 2. Одновременно хост 4 запрашивает канал с пропускной способностью 2 Мбайт/с для потока от хоста 1, а хост 5 запрашивает канал с пропускной способностью 1 Мбайт/с для потока от хоста 2. Какую суммарную пропускную способность необходимо зарезервировать для удовлетворения перечисленных запросов на маршрутизаторах A, B, C, E, H, J, K и L?

21.    Маршрутизатор может обрабатывать 2 млн пакетов в секунду Нагрузка составляет в среднем 1,5 млн пакетов в секунду Сколько времени уйдет на формирование очередей и обслуживание пакетов процессорами, если путь от источника до приемника содержит 10 маршрутизаторов?

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

23.    Допустим, хост А соединен с маршрутизатором R1. Тот, в свою очередь, соединен с другим маршрутизатором, R2, а R2 — с хостом B. Сообщение TCP, содержащее 900 байт данных и 20 байт TCP-заголовка, передается IP-программе, установленной на хосте А, для доставки его хосту В. Каковы будут значения полей Общая длина, Идентификатор, DF, MF и Сдвиг фрагмента IP-заголовка каждого пакета, передающегося по трем линиям. Предполагается, что на линии A-R1 максимальный размер кадра равен 1024 байта, включая 14-байтный заголовок кадра, на линии R1-R2 максимальный размер кадра составляет 512 байт, включая 8-байтный заголовок кадра, и на линии R2-B максимальный размер кадра составляет 512 байт, включая 12-байтный заголовок кадра.

24.    Маршрутизатор обрабатывает IP-пакеты, общая длина которых (включая данные и заголовок) равна 1024 байт. Предполагая, что пакеты живут в течение 10 с, сосчитайте максимальную скорость линии, с которой может работать маршрутизатор без опасности зацикливания в пространстве идентификационных номеров IP-дейтаграммы.

25.    IP-дейтаграмма, использующая параметр Строгая маршрутизация от источника, должна быть фрагментирована. Копируется ли этот параметр в каждый фрагмент, или достаточно поместить его в первый фрагмент? Поясните свой ответ.

26.    Допустим, вместо 16 бит в адресе класса B для обозначения номера сети отводилось бы 20 бит. Сколько было бы тогда сетей класса B?

27.    Преобразуйте IP-адрес, шестнадцатеричное представление которого равно C22F 1582, в десятичный формат, разделенный точками.

28.    Маска подсети сети Интернета равна 255.255.240.0. Чему равно максимальное число хостов в ней?

29.    IP-адреса подходят для обозначения сетей, а Ethemet-адреса — нет. Как вы думаете, почему это так?

30.    Существует множество адресов, начинающихся с IP-адреса 198.16.0.0. Допустим, организации A, B, C и D запрашивают соответственно 4000, 2000, 4000 и 8000 адресов. Для каждой из них укажите первый и последний выданные адреса, а также маску вида w.x.y.z/s.

31.    Маршрутизатор только что получил информацию о следующих IP-адресах: 57.6.96.0/21, 57.6.112.0/21 и 57.6.120.0/21. Если для них используется одна и та же исходящая линия, можно ли их агрегировать? Если да, то во что? Если нет, то почему?

32.    Набор IP-адресов с 29.18.0.0 по 19.18.128.255 агрегирован в 29.18.0.0/17. Тем не менее остался пробел из 1024 не присвоенных адресов с 29.18.60.0 по 29.18.63.255, которые внезапно оказались присвоены хосту, использующему другую исходящую линию. Необходимо ли теперь разделить агрегированный адрес на составляющие, добавить в таблицу новый блок, а потом посмотреть, можно ли что-нибудь агрегировать? Если нет, тогда что можно сделать?

33.    Маршрутизатор содержит следующие записи (CIDR) в своей таблице маршрутизации:

Адрес/маска

Следующий переход

135.46.56.0/22

Интерфейс 0

135.46.60.0/22

Интерфейс 1

192.53.40.0/23

Маршрутизатор 1

По умолчанию

Маршрутизатор 2

Куда направит маршрутизатор пакеты со следующими IP-адресами?

1)    135.46.63.10

2)    135.46.57.14

3)    135.46.52.2

4)    192.53.40.7

5)    192.53.56.7

34.    Многие компании придерживаются стратегии установки двух и более маршрутизаторов, соединяющих компанию с провайдером, что гарантирует некоторый запас прочности на случай, если один из маршрутизаторов выйдет из строя. Применима ли такая политика при использовании NAT? Ответ поясните.

35.    Вы рассказали товарищу про протокол ARP. Когда вы закончили объяснения, он сказал: «Ясно. ARP предоставляет услуги сетевому уровню, таким образом, он является частью канального уровня.» Что вы ему ответите?

36.    Опишите способ сборки пакета из фрагментов в пункте назначения.

37.    В большинстве алгоритмов сборки IP-дейтаграмм из фрагментов используется таймер, чтобы из-за потерянного фрагмента буфер, в котором производится повторная сборка, не оказался занят остальными фрагментами дейтаграммы. Предположим, дейтаграмма разбивается на четыре фрагмента. Первые три фрагмента прибывают к получателю, а четвертый задерживается в пути. У получателя истекает период ожидания, и три фрагмента, хранившиеся в его памяти, удаляются. Немного позднее наконец приползает последний фрагмент. Как следует с ним поступить?

38.    В IP контрольная сумма покрывает только заголовок, но не данные. Почему, как вы полагаете, была выбрана подобная схема?

39.    Особа, живущая в Бостоне, едет в Миннеаполис и берет с собой свой персональный компьютер. К ее удивлению, локальная сеть в Миннеаполисе является беспроводной локальной сетью IP, поэтому ей нет необходимости подключать свой компьютер. Нужно ли, тем не менее, проходить процедуру с внутренним и внешним агентом, чтобы электронная почта и другой трафик прибывали правильно?

40.    Протокол IPv6 использует 16-байтовые адреса. На какое время хватит этих адресов, если каждую пикосекунду назначать блок в 1 млн адресов?

41.    Поле Протокол, используемое в заголовке IPv4, отсутствует в фиксированном заголовке IPv6. Почему?

42.    Должен ли протокол ARP быть изменен при переходе на шестую версию протокола IP? Если да, то являются ли эти изменения концептуальными или техническими?

43.    Напишите программу, моделирующую маршрутизацию методом заливки. Каждый пакет должен содержать счетчик, уменьшаемый на каждом маршрутизаторе. Когда счетчик уменьшается до нуля, пакет удаляется. Время дискретно, и каждая линия обрабатывает за один интервал времени один пакет. Создайте три версии этой программы: с заливкой по всем линиям; с заливкой по всем линиям, кроме входной линии; с заливкой только k лучших линий (выбираемых статически). Сравните заливку с детерминированной маршрутизацией (k = 1) с точки зрения задержки и использования пропускной способности.

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

45.    Напишите функцию, осуществляющую пересылку в IP-маршрутизаторе. У процедуры должен быть один параметр — IP-адрес. Имеется доступ к глобальной таблице, представляющей собой массив из троек значений. Каждая тройка содержит следующие целочисленные значения: IP-адре^ маску подсети и исходящую линию. Функция ищет IP-адрес в таблице, используя CIDR, и возвращает номер исходящей линии.

46.    Используя программы traceroute (UNIX) или tracert (Windows), исследуйте маршрут от вашего компьютера до различных университетов мира. Составьте список трансокеанских линий. Вот некоторые адреса:

www.berkeley.edu (Калифорния) www.mit.edu (Массачусетс) www.vu.nl (Амстердам) www.ucl.ac.uk (Лондон) www.usyd.edu.au (Сидней) www.u-tokyo.ac.jp (Токио) www.uct.ac.za (Кейптаун)

Глава 6

Транспортный уровень

Вместе с сетевым уровнем транспортный уровень составляет сердцевину всей иерархии протоколов. Сетевой уровень обеспечивает сквозную доставку пакетов при помощи дейтаграмм и виртуальных каналов. Основанный на сетевом уровне транспортный уровень отвечает за передачу данных от процесса на машине-источнике до процесса на машине-адресате, предоставляя необходимый уровень надежности вне зависимости от физических характеристик использующихся сетей. Он создает абстракции, с помощью которых приложения могут работать в сети. Без транспортного уровня вся концепция многоуровневых протоколов потеряет смысл. В данной главе мы подробно рассмотрим транспортный уровень, включая его сервисы и выбор подходящей схемы API, позволяющей решить проблемы надежности, подключения и перегрузок, а также протоколы (такие как TCP и UDP) и производительность.

6.1.    Транспортный сервис

В следующих разделах мы познакомимся с транспортным сервисом. Мы рассмотрим виды сервисов, предоставляемых прикладному уровню. Чтобы наш разговор не был слишком абстрактным, мы разберем два набора базовых операций транспортного уровня. Сначала рассмотрим простой (но не применяемый на практике) набор, просто чтобы показать основные идеи, а затем — реально применяемый в Интернете интерфейс.

6.1.1.    Услуги, предоставляемые верхним уровням

Конечная цель транспортного уровня заключается в предоставлении эффективных, надежных и экономичных услуг (сервисов) передачи данных своим пользователям, которыми обычно являются процессы прикладного уровня. Для достижения этой цели транспортный уровень пользуется услугами, предоставляемыми сетевым уровнем. Программа и/или аппаратура, выполняющая работу транспортного уровня, называется транспортной подсистемой или транспортным объектом (transport entity). Транспортная подсистема может располагаться в ядре операционной системы, в библиотечном модуле, загруженном сетевым приложением, в отдельном пользовательском процессе или даже в сетевой интерфейсной плате. Первые два варианта чаще всего встречаются в сети Интернет. Логическая взаимосвязь сетевого, транспортного и прикладного уровней проиллюстрирована на рис. 6.1.

Рис. 6.1. Сетевой, транспортный и прикладной уровни

Сервисы транспортного уровня, как и сервисы сетевого уровня, делятся на сервисы с установлением соединения и сервисы без установления соединения. Транспортный сервис с установлением соединения во многом похож на аналогичный сетевой сервис. В обоих случаях соединение проходит три этапа: установление соединения, передача данных и разъединение. Адресация и управление потоком на разных уровнях также схожи. Более того, похожи друг на друга и сервисы без установления соединения разных уровней. Однако следует обратить внимание на то, что реализовать комбинацию транспортного сервиса без установления соединения и сетевого сервиса с установлением соединения часто достаточно трудно, так как для этого придется разрывать только что созданное соединение сразу же после отправки пакета.

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

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

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

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

Именно по этой причине часто проводится разграничение между уровнями с первого по четвертый и уровнями выше четвертого. Нижние четыре уровня можно рассматривать как поставщика транспортных услуг (transport service provider), а верхние уровни — как потребителя транспортных услуг (transport service user). Разделение на поставщика и пользователя оказывает серьезное влияние на устройство уровней и помещает транспортный уровень на ключевую позицию, поскольку он формирует основную границу между поставщиком и пользователем надежного сервиса передачи данных. Именно этот уровень виден приложениям.

6.1.2. Базовые операции транспортного сервиса

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

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

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

В качестве примера рассмотрим два процесса, работающих на одной машине, соединенных каналом в системе UNIX (или с помощью любого средства, позволяющего обеспечить взаимодействие процессов). Эти процессы предполагают, что соединение между ними абсолютно идеально. Они не желают знать о подтверждениях, потерянных пакетах, перегрузках и т. п. Им требуется стопроцентно надежное соединение. Процесс A помещает данные в один конец канала, а процесс B извлекает их на другом. Именно для этого и предназначен транспортный сервис с установлением соединения — скрывать несовершенство сетевого сервиса, чтобы пользовательские процессы могли считать, что существует безошибочный поток битов, даже если процессы выполняются на разных машинах.

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

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

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

Чтобы понять, как могут быть использованы эти операции, рассмотрим приложение, состоящее из сервера и нескольких удаленных клиентов. Вначале сервер выполняет операцию LISTEN — обычно для этого вызывается библиотечная процедура, которая обращается к системе. В результате сервер блокируется, пока клиент не обратится к нему. Когда клиент хочет поговорить с сервером, он выполняет операцию CONNECT. Транспортная подсистема выполняет эту операцию, блокируя обратившегося к ней клиента и посылая пакет серверу. Поле данных пакета содержит сообщение транспортного уровня, адресованное транспортной подсистеме сервера.

Следует сказать пару слов о терминологии. За неимением лучшего термина, для сообщений, посылаемых одной транспортной подсистемой другой транспортной подсистеме, нам придется использовать термин сегмент (segment). Это обозначение используется в TCP, UDP и других интернет-протоколах. В более старых протоколах применяется несколько неуклюжее название TPDU (Transport Protocol Data Unit — модуль данных транспортного протокола). Сейчас оно практически не используется, однако вы можете встретить его в старых статьях и книгах.

Таблица 6.1. Базовые операции простого транспортного сервиса

Базовая операция

Посланный сегмент

Значение

LISTEN (ОЖИДАТЬ)

(нет)

Блокировать сервер, пока какой-либо процесс не попытается соединиться

CONNECT

(СОЕДИНИТЬ)

CONNECTION REQUEST (ЗАПРОС СОЕДИНЕНИЯ)

Активно пытаться установить соединение

SEND (ПОСЛАТЬ)

ДАННЫЕ

Послать информацию

RECEIVE

(ПОЛУЧИТЬ)

(нет)

Блокировать сервер, пока не прибудут данные

DISCONNECT

(РАЗЪЕДИНИТЬ)

DISCONNECTION REQUEST (ЗАПРОС РАЗЪЕДИНЕНИЯ)

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

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

Рис. 6.2. Вложенность сегментов, пакетов и кадров

Итак, вернемся к нашему примеру общения клиента и сервера. В результате запроса клиента CONNECT серверу посылается сегмент, содержащий CONNECTION REQUEST (запрос соединения). Когда он прибывает, транспортная подсистема проверяет, заблокирован ли сервер операцией LISTEN (то есть заинтересован ли сервер в обработке запросов). Затем она разблокирует сервер и посылает обратно клиенту сегмент CONNECTION ACCEPTED (соединение принято). Получив этот сегмент, клиент разблокируется, после чего соединение считается установленным.

Теперь клиент и сервер могут обмениваться данными с помощью базовых операций SEND и RECEIVE. В простейшем случае каждая из сторон может использовать блокирующую операцию RECEIVE для перехода в режим ожидания сегмента, посылаемого противоположной стороной при помощи операции SEND. Когда сегмент прибывает, получатель разблокируется. Затем он может обработать полученный сегмент и послать ответ. Такая схема прекрасно работает, пока обе стороны помнят, чей черед посылать, а чей — принимать.

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

Когда соединение больше не требуется, оно должно быть разорвано, чтобы можно было освободить место в таблицах двух транспортных подсистем. Разъединение существует в двух вариантах: симметричном и асимметричном. В асимметричном варианте любой потребитель транспортных услуг может вызвать примитив DISCONNECT, в результате чего удаленной транспортной сущности будет послан управляющий сегмент DISCONNECTION REQUEST (запрос разъединения). После получения сегмента удаленной транспортной подсистемой соединение разрывается.

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

Диаграмма состояний для установления и разрыва соединения показана на рис. 6.3. Каждый переход вызывается каким-то событием — операцией, выполненной локальным пользователем транспортного сервиса, или входящим пакетом. Для простоты мы будем считать, что каждый сегмент подтверждается отдельно. Мы также предполагаем, что используется модель симметричного разъединения, в которой клиент делает первый ход. Обратите внимание на наивность этой модели. Позднее, когда мы будем говорить о TCP, мы рассмотрим более реалистичные модели.

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

6.1.3. Сокеты Беркли

Теперь рассмотрим другой набор базовых операций транспортного уровня — базовые операции сокетов (иногда называемых гнездами), используемые для протокола TCP (Transmission Control Protocol — протокол управления передачей). Впервые сокеты стали применяться в 1983 году в операционной системе Berkeley UNIX 4.2BSD. Очень скоро они стали популярными и сейчас широко используются для интернет-программирования в большинстве операционных систем, особенно UNIX; кроме того, существует специальный API, предназначенный для программирования сокетов в системе Windows — «winsock».

Эти базовые операции приведены в табл. 6.2. Модель сокетов во многом подобна рассмотренной выше модели, но обладает большей гибкостью и предоставляет больше возможностей. Сегменты, соответствующие этой модели, будут рассматриваться ниже в этой главе.

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

Таблица 6.2. Базовые операции сокетов для TCP

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

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

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

Теперь посмотрим на этот процесс со стороны клиента. В этом случае также сначала с помощью операции SOCKET должен быть создан сокет, но операция BIND здесь не требуется, так как используемый адрес не имеет значения для сервера. CONNECT блокирует вызывающего и инициирует активный процесс соединения. Когда этот процесс завершается (то есть когда соответствующий сегмент, посланный сервером, получен), процесс клиента разблокируется, и соединение считается установленным. После этого обе стороны могут использовать SEND и RECIEVE для передачи и получения данных по полнодуплексному соединению. Могут также применяться стандартные UNIX-вызовы READ и WRITE, если нет нужды в использовании специальных свойств SEND и RECIEVE.

В модели сокетов используется симметричный разрыв соединения. Соединение разрывается, когда обе стороны выполняют операцию CLOSE.

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

Преимущество сокет-API состоит в том, что приложение может использовать его и для других транспортных сервисов. К примеру, с помощью сокетов можно реализовать транспортный сервис без установления соединения. В таком случае операция CONNECT будет задавать адрес удаленного узла, а SEND и RECEIVE — отправлять и получать дейтаграммы. (Иногда используется расширенный набор вызовов — например, операции SENDTO и RECEIVEFROM, позволяющие приложению не ограничиваться одним транспортным узлом.) Иногда сокеты используются с транспортными протоколами, в которых вместо байтового потока применяется поток сообщений и которые могут включать или не включать управление перегрузкой. К примеру, DCCP (Datagram Congestion Control Protocol дейтаграммный протокол с управлением перегрузкой) является вариантом UDP, включающим управление перегрузкой (Rohler и др., 2006). Задачу выбора необходимого сервиса решают в первую очередь потребители транспортных услуг.

Тем не менее последнее слово в вопросе транспортных интерфейсов, скорее всего, останется не за сокетами. Довольно часто приложениям приходится работать с группой связанных потоков — так, например, браузер может одновременно запрашивать у сервера несколько объектов. В таком случае применение сокетов обычно означает, что для каждого объекта будет использоваться один поток, и в результате управление перегрузкой будет выполняться отдельно для каждого потока (а не для всей группы), что, безусловно, является далеко не оптимальным вариантом, поскольку управление набором потоков ложится на плечи приложения. Чтобы более эффективно обрабатывать группы связанных потоков и уменьшить роль приложения в этом процессе, были созданы новые протоколы и интерфейсы. В качестве примеров приведем SCTP (Stream Control Transmission Protocol протокол передачи с управлением потоками), описанный в RFC 4960, и SST (Structured Stream Transport иерархическая поточная транспортировка данных) (Ford, 2007). Эти протоколы слегка изменяют сокет-API для удобства работы с группами потоков, обеспечивая ряд новых возможностей, таких как работа со смешанным трафиком (с установлением соединения и без) и даже поддержка множественных сетевых путей. О том, насколько они успешны, мы узнаем по прошествии некоторого времени.

6.1.4. Пример программирования сокета: файл-сервер для Интернета

Чтобы узнать, как выполняются настоящие вызовы для сокета, рассмотрим программу, демонстрирующую работу клиента и сервера, представленную в листинге 6.1. Имеется примитивный файл-сервер, работающий в Интернете и использующий его клиент.

У программы много ограничений (о которых еще будет сказано), но в принципе данный код, описывающий сервер, может быть скомпилирован и запущен на любой UNIX-системе, подключенной к Интернету. Код, описывающий клиента, может быть запущен с определенными параметрами. Это позволит ему получить любой файл, к которому у сервера есть доступ. Файл отображается на стандартном устройстве вывода, но, разумеется, может быть перенаправлен на диск или какому-либо процессу.

Листинг 6.1. Программы использования сокетов для клиента и сервера

Рассмотрим сперва ту часть программы, которая описывает сервер. Она начинается с включения некоторых стандартных заголовков, последние три из которых содержат основные структуры и определения, связанные с Интернетом. Затем SERVER_PORT определяется как 12345. Значение выбрано случайным образом. Любое число от 1024 до 65535 подойдет с не меньшим успехом, если только оно не используется каким-либо другим процессом; порты с номерами 1023 и ниже зарезервированы для привилегированных пользователей.

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

После объявления локальных переменных начинается сама программа сервера. Вначале она инициализирует структуру данных, которая будет содержать IP-адрес сервера. Эта структура будет связана с серверным сокетом. Вызов memset полностью обнуляет структуру данных. Последующие три присваивания заполняют три поля этой структуры. Последнее из них содержит порт сервера. Функции htonl и htons занимаются преобразованием значений в стандартный формат, что позволяет программе нормально выполняться как на машинах с представлением числовых разрядов little-endian (например, Intel x86), так и с представлением big-endian (например, SPARC). Детали их семантики здесь роли не играют.

После этого сервером создается и проверяется на ошибки (определяется по s < 0) сокет. В окончательной версии программы сообщение об ошибке может быть чуть более понятным. Вызов setsockopt нужен для того, чтобы порт мог использоваться несколько раз, а сервер — бесконечно, обрабатывая запрос за запросом. Теперь IP-адрес привязывается к сокету и выполняется проверка успешного завершения вызова bind. Конечным этапом инициализации является вызов listen, свидетельствующий о готовности сервера к приему входящих вызовов и сообщающий системе о том, что нужно ставить в очередь до QUEUE_SIZE вызовов, пока сервер обрабатывает текущий вызов. При заполнении очереди прибытие новых запросов спокойно игнорируется.

В этом месте начинается основной цикл программы, который никогда не покидается. Его можно остановить только извне. Вызов accept блокирует сервер на то время, пока клиент пытается установить соединение. Если вызов завершается успешно, accept возвращает дескриптор (описатель) сокета, который можно использовать для чтения и записи, аналогично тому, как файловые дескрипторы (описатели) могут применяться для чтения и записи в каналы. Однако, в отличие от однонаправленных каналов, сокеты двунаправлены, поэтому для чтения (и записи) данных из соединения можно использовать sa (принятый сокет). Файловые дескрипторы канала могут использоваться для чтения или записи, но не для того и другого одновременно.

После установления соединения сервер считывает имя файла. Если оно пока недоступно, сервер блокируется, ожидая его. Получив имя файла, сервер открывает файл и входит в цикл, который читает блоки данных из файла и записывает их в сокет. Это продолжается до тех пор, пока не будут скопированы все запрошенные данные. Затем файл закрывается, соединение разрывается и начинается ожидание нового вызова. Данный цикл повторяется бесконечно.

Теперь рассмотрим часть кода, описывающую клиента. Чтобы понять, как работает программа, необходимо вначале разобраться, как она запускается. Если она называется client, ее типичный вызов будет выглядеть так:

client flits.csvu.nl /usr/tom/filename >f

Этот вызов сработает только в том случае, если сервер расположен по адресу flits. cs.vu.nl, файл /usr/tom/filename существует и у сервера есть доступ по чтению для этого файла. Если вызов произведен успешно, файл передается по Интернету и записывается на место f, после чего клиентская программа заканчивает свою работу. Поскольку серверная программа продолжает работать, клиент может быть запущен снова с новыми запросами на получение файлов.

Клиентская программа начинается с подключения файлов и объявлений. Работа начинается с проверки корректности числа аргументов (argc = 3 означает, что в строке запуска содержалось имя программы и два аргумента). Обратите внимание на то, что argv[1] содержит имя сервера (например, flits.cs.vu.nl) и переводится в IP-адрес с помощью gethostbyname. Для поиска имени функция использует DNS. Мы будем изучать технологию DNS в главе 7.

Затем создается и инициализируется сокет, после чего клиент пытается установить TCP-соединение с сервером посредством connect. Если сервер включен, работает на указанной машине, соединен с SERVER_PORT и либо простаивает, либо имеет достаточно места в очереди listen (очереди ожидания), то соединение с клиентом будет рано или поздно установлено. По данному соединению клиент передает имя файла, записывая его в сокет. Количество отправленных байтов на единицу превышает требуемое для передачи имени, поскольку нужен еще нулевой байт-ограничитель, с помощью которого сервер может понять, где кончается имя файла.

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

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

Эти две программы (как и другие материалы, связанные с этой книгой) можно найти на веб-сайте книги по адресу http://www.prenhall.com/tanenbaum.

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

щью данной программы можно организовать полноценный работающий файл-сервер для Интернета. Более подробную информацию можно найти в (Donahoo и Calvert, 2008, 2009).

6.2. Элементы транспортных протоколов

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

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

Рис. 6.4. Окружение: а — канального уровня; б — транспортного уровня

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

Во-вторых, процесс установки соединения по проводу (рис. 6.4, а) прост: противоположная сторона всегда присутствует (если только она не вышла из строя). В любом случае, работы не очень много. Даже в случае беспроводного соединения ситуация отличается не сильно. Простой отправки сообщения достаточно, чтобы оно дошло до всех адресов назначения. Если подтверждение о получении не приходит (вследствие ошибок), сообщение может быть отправлено повторно. На транспортном уровне начальная установка соединения, как будет показано ниже, происходит достаточно сложно.

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

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

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

6.2.1. Адресация

Когда один прикладной процесс желает установить соединение с другим прикладным процессом, он должен указать, с кем именно он хочет связаться. (У не требующего соединений транспортного сервиса проблемы такие же: кому следует посылать каждое сообщение?) Применяемый обычно метод состоит в определении транспортных адресов, к которым процессы могут посылать запросы на установку соединения. В Интернете такие конечные точки называются портами. Мы будем пользоваться нейтральным термином TSAP (Transport Service Access Point точка доступа к услугам транспортного уровня) для обозначения конечных точек на транспортном уровне. Аналогичные конечные точки сетевого уровня (то есть адреса сетевого уровня) называются NSAP (Network Service Access Point точка доступа к сетевым услугам). Примерами NSAP являются IP-адреса.

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

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

1. Процесс почтового сервера подсоединяется к точке доступа TSAP 1522 на хосте 2 и ожидает входящего вызова. Вопрос о том, как процесс соединяется с TSAP, лежит за пределами сетевой модели и целиком зависит от локальной операционной системы. Например, может вызываться примитив, подобный LISTEN.

2.    Прикладной процесс хоста 1 желает отправить почтовое сообщение, и поэтому он подсоединяется к TSAP 1208 и обращается к сети с запросом CONNECT, указывая TSAP 1208 на хосте 1 в качестве адреса отправителя и TSAP 1522 на хосте 2 в качестве адреса получателя. Это действие в результате приводит к установке транспортного соединения между прикладным процессом и сервером.

3.    Прикладной процесс отправляет почтовое сообщение.

4.    Почтовый сервер отвечает, что сообщение будет доставлено.

5.    Транспортное соединение разрывается.

Рис. 6.5. Точки доступа к услугам транспортного и сетевого уровня и транспортные соединения

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

Нарисованная выше картинка всем хороша, но мы обошли стороной один маленький вопрос: как пользовательский процесс хоста 1 узнает, что почтовый сервер соединен с TSAP 1522? Возможно, почтовый сервер подключается к TSAP 1522 в течение долгих лет, и постепенно об этом узнают все пользователи сети. В этом случае службы имеют постоянные TSAP-адреса, хранящиеся в файлах, расположенных в известных местах. Так, например, в /etc/services UNIX-систем перечисляются серверы, за которыми жестко закреплены определенные порты, с указанием этих портов — в частности, там указано, что почтовый сервер использует TCP порт 25.

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

Чтобы справиться с этой ситуацией, может использоваться другая схема. В этой модели используется специальный процесс, называющийся сопоставителем портов (portmapper). Чтобы найти TSAP-адрес, соответствующий данному имени службы, например «BitTorrent», пользователь устанавливает соединение с сопоставителем портов (TSAP-адрес которого всем известен). Затем пользователь посылает сообщение с указанием названия нужной ему услуги, и сопоставитель портов сообщает ему TSAP-адрес этой службы. После этого пользователь разрывает соединение с сопоставителем портов и устанавливает новое соединение с нужной ему службой.

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

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

Рис. 6.6. Пользовательский процесс хоста 1 устанавливает соединение с почтовым сервером хоста 2 через обрабатывающий сервер

Так как многие из серверных процессов, существующих на конкретной машине, используются редко, слишком расточительным делом оказывается поддержка всех их в активном состоянии с постоянными TSAP-адресами. Альтернативный вариант показан в упрощенном виде на рис. 6.6. Он называется протоколом начального соединения (initial connection protocol). Вместо того чтобы назначать всем возможным серверам хорошо известные TSAP-адреса, каждая машина, желающая предоставлять услуги удаленным пользователям, обзаводится специальным обрабатывающим сервером (process server), действующим как прокси (посредник) для менее активно используемых серверов. В UNIX-системах такой сервер называется inetd. Он прослушивает одновременно несколько портов, ожидая запроса на соединение. Потенциальные пользователи начинают с того, что посылают запрос CONNECT, указывая TSAP-адрес нужной им службы. Если никакой сервер их не ждет, они получают соединение с обрабатывающим сервером, как показано на рис. 6.6, а.

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

6.2.2. Установка соединения

Установка соединения, хотя и просто звучит, неожиданно оказывается весьма непростым делом. На первый взгляд, должно быть достаточно одной транспортной подсистеме послать адресату сегмент с запросом соединения CONNECTION REQUEST и услышать в ответ CONNECTION ACCEPTED (соединение принято). Неприятность заключается в том, что сеть может потерять, задержать, повредить или дублировать пакеты.

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

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

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

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

случае сеть будет ненадежной и может неожиданно сломаться, даже не сообщив об ошибке.

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

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

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

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

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

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

1.    Проектирование сети с ограничениями.

2.    Помещение в каждый пакет счетчика транзитных участков.

3.    Помещение в каждый пакет временного штампа.

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

На практике нужно гарантировать не только то, что пакет мертв, но и что все его подтверждения также мертвы. Поэтому вводится период T, который в несколько раз превышает максимальное время жизни пакета. Для каждой сети максимальное время жизни пакета — это константа, выбранная с запасом; для сети Интернет она составляет 120 с. На какое число умножается максимальное время жизни пакета, зависит от протокола, и это влияет только на длительность интервала времени T. Если подождать в течение интервала времени T с момента отправки пакета, то можно быть уверенным, что все его следы уничтожены и что пакет не возникнет вдруг как гром среди ясного неба.

При ограниченном времени жизни пакетов можно разработать надежный и практичный способ отвергать задержавшиеся дублированные сегменты. Автором описанного ниже метода является Томлинсон (Tomlinson, 1975); позднее он был улучшен Саншайном (Sunshine) и Далалом (Dalal). Его варианты широко применяются на практике, и одним из примеров применения является TCP.

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

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

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

При установке соединения младшие k бит часов используются в качестве k-битного начального порядкового номера. Таким образом, в отличие от протоколов, описанных в главе 3, каждое соединение начинает нумерацию своих сегментов с разных чисел.

Диапазон этих номеров должен быть достаточно большим, чтобы к тому моменту, когда порядковые номера сделают полный круг, старые сегменты с такими же номерами уже давно исчезли. Линейная зависимость порядковых номеров от времени показана на рис. 6.7. Запретная зона показывает, в какой момент времени определенные порядковые номера сегментов являются недействительными. При отправке сегмента с порядковым номером из этой зоны он может задержаться и сыграть роль другого пакета с таким же номером, который будет отправлен позже. К примеру, если хост выходит из строя и возобновляет работу в момент времени 70 с, он будет использовать начальные порядковые номера на основе показаний часов; хост не начинает отсчет с наименьшего порядкового номера в запретной зоне.

Рис. 6.7. Сегменты не могут заходить в запретную зону (а); проблема ресинхронизации (б)

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

Чтобы порядковые номера пакетов не попадали в запретную зону, необходимо обратить внимание на следующее.

Неприятности у протокола могут возникнуть по двум причинам. Если хост посылает слишком быстро и слишком много данных, кривая используемых в действительности порядковых номеров может оказаться круче линии зависимости начальных номеров от времени, в результате чего порядковый номер попадет в запретную зону. Чтобы этого не произошло, скорость передачи данных в каждом открытом соединении должна быть ограничена одним сегментом за единицу времени. Кроме того, это означает, что транспортная подсистема после восстановления, прежде чем открывать новое соединение, должна подождать, пока изменят свое состояние часы, чтобы один и тот же номер не использовался дважды. Следовательно, интервал изменения состояния часов должен быть коротким (1 мкс или меньше). Но также часы не должны идти слишком быстро (относительно порядковых номеров). Если скорость

часов равна C, а пространство порядковых номеров имеет размер S, условие S/C > T является обязательным, чтобы порядковые номера не сделали полный круг слишком быстро.

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

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

Для разрешения этой специфической проблемы Томлинсон (1975) предложил тройное рукопожатие (three-way handshake). Этот протокол установления соединения предполагает, что одна из сторон проверяет, является ли соединение все еще действующим. Нормальная процедура установления соединения показана на рис. 6.8, а. Хост 1 инициирует установление, выбирая порядковый номер х, и посылает сегмент CONNECTION REQUEST, содержащий этот начальный порядковый номер, хосту 2. Хост 2 отвечает сегментом ACK, подтверждая х и объявляя свой начальный порядковый номер у. Наконец, хост 1 подтверждает выбранный хостом 2 начальный порядковый номер в первом посылаемом им информационном сегменте.

Рассмотрим теперь работу «тройного рукопожатия» в присутствии задержавшегося дубликата управляющего сегмента. На рис. 6.8, б первый сегмент представляет собой задержавшийся дубликат сегмента CONNECTION REQUEST от старого соединения. Этот сегмент прибывает на хост 2 тайком от хоста 1. Хост 2 реагирует на этот сегмент отправкой хосту 1 сегмента ACK, таким образом, прося хост 1 подтвердить, что тот действительно пытался установить новое соединение. Когда хост 1 отказывается это сделать, хост 2 понимает, что он был обманут задержавшимся дубликатом, и прерывает соединение. Таким образом, задержавшийся дубликат не причиняет вреда.

При наихудшем сценарии оба сегмента — CONNECTION REQUEST и ACK — блуждают по подсети. Этот случай показан на рис. 6.8, в. Как и в предыдущем примере, хост 2 получает задержавшийся сегмент CONNECTION REQUEST и отвечает на него. В этом месте следует обратить внимание на то, что хост 2 предложил использовать у в качестве начального порядкового номера для трафика от хоста 2 к хосту 1, хорошо зная, что сегментов, содержащих порядковый номер у, или их подтверждений в данный момент в сети нет. Когда хост 2 получает второй задержавшийся сегмент, он понимает, что это дубликат, так как в этом модуле подтверждается не у, а z. Здесь важно понять, что не существует такой комбинации сегментов, которая заставила бы протокол ошибиться и случайно установить соединение, когда оно никому не нужно.

Рис. 6.8. Три сценария установки соединения с помощью «тройного рукопожатия» (CR означает CONNECTION REQUEST): а — нормальная работа; б — появление старого дубликата CR; в — дубликат сегмента CR и дубликат сегмента ACK

TCP использует «тройное рукопожатие» для установки соединения. Внутри соединения к 32-битному порядковому номеру добавляется метка времени, чтобы он не мог использоваться повторно в течение максимального времени жизни пакета, даже если скорость соединения составляет несколько гигабит в секунду. Этот механизм был добавлен в TCP для решения проблем, возникших при использовании быстрых линий. Он описан в RFC 1323 и называется PAWS (Protection Against Wrapped Sequence numbers детектирование повторного использования порядковых номеров). Для работы с несколькими соединениями, имеющими начальные порядковые номера, до появления PAWS протокол TCP применял метод, использующий показания часов (см. выше). Однако этот метод оказался неэффективным с точки зрения безопасности.

Благодаря использованию часов злоумышленники могли легко угадать следующий начальный порядковый номер, и таким образом обманув схему «тройного рукопожатия», инициировать ложное соединение. Поэтому на практике используются псевдослучайные начальные порядковые номера. Но для таких порядковых номеров, со стороны кажущихся абсолютно случайными, все-таки важно, чтобы они не повторялись в течение определенного промежутка времени. Иначе задержавшиеся дубликаты могут вызвать серьезные неполадки в работе сети.

6.2.3. Разрыв соединения

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

Асимметричный разрыв связи является внезапным и может привести к потере данных. Рассмотрим сценарий, показанный на рис. 6.9. После установки соединения хост 1 посылает сегмент, который успешно добирается до хоста 2. Затем хост 1 посылает другой сегмент. К несчастью, хост 2 посылает DISCONNECTION REQUEST (запрос разъединения — DR) прежде, чем прибывает второй сегмент. В результате соединение разрывается, а данные теряются.

Рис. 6.9. Внезапное разъединение с потерей данных

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

Симметричное разъединение хорошо подходит для тех случаев, когда у каждой стороны есть фиксированное количество данных для передачи, и каждая сторона точно знает, когда эти данные заканчиваются. В других случаях определить, что работа закончена и соединение может быть прервано, не так просто. Можно представить себе протокол, в котором хост 1 говорит: «Я закончил. Вы тоже закончили?» Если хост 2 отвечает: «Я тоже закончил. До свидания», соединение можно безо всякого риска разъединять.

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

Рис. 6.10. Проблема двух армии

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

Предположим, командир первой армии синих посылает следующее сообщение: «Я предлагаю атаковать 29 марта, на рассвете. Сообщите ваше мнение». Теперь предположим, что сообщение успешно доставляется и что командир 2-й армии синих соглашается, а его ответ успешно доставляется обратно в 1-ю армию синих. Состоится ли атака? Вероятно, нет, так как командир 2-й армии не уверен, что его ответ получен. Если нет, то 1-я армия синих не будет атаковать, и было бы глупо с его стороны в одиночку ввязываться в сражение.

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

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

Чтобы увидеть, какое отношение проблема двух армий имеет к разрыву соединения, просто замените слово «атаковать» на «разъединить». Если ни одна сторона не готова разорвать соединение до тех пор, пока она не уверена, что другая сторона также готова к этому, то разъединение не произойдет никогда.

На практике, чтобы справиться с этой ситуацией, нужно отказаться от идеи договоренности и переложить ответственность на потребителей транспортных услуг, так чтобы каждая сторона приняла независимое решение о том, когда будет выполнена операция. Такую проблему решить проще. На рис. 6.11 показаны четыре сценария разъединения, использующих «тройное рукопожатие». Хотя этот протокол и не безошибочен, обычно он работает успешно.

На рис. 6.11, а показан нормальный случай, в котором один из пользователей посылает запрос разъединения DR (DISCONNECTION REQUEST), чтобы инициировать разрыв соединения. Когда запрос прибывает, получатель посылает обратно также запрос разъединения DR и включает таймер на случай, если запрос потеряется. Когда запрос прибывает, первый отправитель посылает в ответ на него сегмент с подтверждением ACK и разрывает соединение. Наконец, когда прибывает ACK, получатель также разрывает соединение. Разрыв соединения означает, что транспортная подсистема удаляет информацию об этом соединении из своей таблицы открытых соединений и сигнализирует о разрыве соединения владельцу соединения (потребителю транспортного сервиса). Эта процедура отличается от применения пользователем операции DISCONNECT.

Если последний сегмент с подтверждением теряется (рис. 6.11, б ), ситуацию спасает таймер. Когда время истекает, соединение разрывается в любом случае.

Теперь рассмотрим случай потери второго запроса разъединения DR. Пользователь, инициировавший разъединение, не получит ожидаемого ответа, у него истечет время ожидания и он начнет все сначала. На рис. 6.11, в показано, как это происходит в случае, если все последующие запросы и подтверждения успешно доходят до адресатов.

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

Хотя такого протокола обычно бывает вполне достаточно, теоретически он может ошибиться, если потеряются начальный запрос разъединения DR и все N повторных попыток. Отправитель сдается и разрывает соединение, тогда как другая сторона ничего не знает о попытках разорвать связь и сохраняет активность. В результате получается полуоткрытое соединение.

Рис. 6.11. Четыре сценария разрыва соединения: а — нормальный случай «тройного рукопожатия»; б — потеряно последнее подтверждение; в — потерян ответ; г — потерян ответ и последующие запросы

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

Чтобы удалять полуоткрытые соединения, можно применять правило, гласящее, что если по соединению в течение определенного времени не прибывает ни одного сегмента, соединение автоматически разрывается. Таким образом, если одна сторона отсоединится, другая обнаружит отсутствие активности и также отсоединится. Это правило также работает для тех случаев, когда соединение разрывается не по инициативе одной из сторон, а по причине невозможности передачи пакетов между этими хостами в сети. Для реализации этого правила каждая сторона должна управлять таймером, перезапускаемым после передачи каждого сегмента. Если этот таймер срабатывает, посылается пустой сегмент — лишь для того, чтобы другая сторона не повесила трубку. С другой стороны, если применяется правило автоматического разъединения и теряется слишком большое количество сегментов подряд, то соединение автоматически разрывается сначала одной стороной, а затем и другой.

На этом мы заканчиваем обсуждение данного вопроса, но теперь должно быть ясно, что разорвать соединение без потери данных не так просто, как это кажется на первый взгляд. Из всего сказанного выше можно сделать вывод, что потребитель транспортных услуг должен принимать участие в решении вопроса о разрыве соединения — транспортная подсистема не может сама с этим справиться. Обратите внимание на то, что хотя TCP обычно использует симметричный разрыв связи (при этом каждая сторона независимо прерывает свое соединение, отправляя пакет FIN после окончания передачи данных), веб-серверы часто передают клиентам специальный пакет RST, сообщающий о мгновенном разрыве соединения — что больше похоже на асимметричный разрыв. Это возможно только благодаря тому, что веб-сервер знаком с процедурой обмена данными. Сначала он получает запрос от клиента (единственное, что отправляет клиент), а затем отсылает клиенту ответ. Таким образом, после отправки этого ответа обмен данными завершен: каждая сторона передала другой то, что требовалось. Поэтому сервер может резко разорвать соединение, отправив клиенту предупреждение. Получив это предупреждение, клиент сразу же разорвет соединение. Если предупреждение не дойдет до клиента, он через какое-то время поймет, что сервер с ним больше не общается, и также разорвет соединение. В любом случае данные будут успешно переданы.

6.2.4. Контроль ошибок и управление потоком данных

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

Оба этих вопроса мы уже обсуждали, когда говорили о канальном уровне. На транспортном уровне используются те же механизмы, которые описаны в главе 3. Вкратце они выглядят так.

1. Фрейм содержит код с обнаружением ошибок (например, CRC-код или контрольную сумму), с помощью которого проверяется, правильно ли была доставлена информация.

2.    Фрейм содержит идентифицирующий порядковый номер и передается отправителем до тех пор, пока не придет подтверждение об успешной доставке. Это называется ARQ (Automatic Repeat reQuest автоматический запрос повторной передачи).

3.    Число кадров, передаваемых отправителем в любой момент времени, обычно ограничено: передача приостанавливается, если подтверждения приходят недостаточно быстро. Если этот максимум равен одному пакету, протокол называется протоколом с остановкой и ожиданием подтверждения (stop-and-wait). Окна большего размера позволяют использовать конвейерную обработку, а также улучшить производительность при работе с длинными и быстрыми линиями.

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

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

Чтобы проиллюстрировать различие в функционировании, обратимся к обнаружению ошибок. Контрольная сумма канального уровня защищает кадр, пока он передается по одному каналу. Контрольная сумма транспортного уровня защищает сегмент, пока он передается по всему пути. Это сквозная проверка, отличная от проверки в каждом канале. Существуют примеры повреждения пакетов даже внутри маршрутизаторов (Saltzer и др., 1984): контрольные суммы канального уровня обеспечивали защиту пакетов, пока они передвигались по каналу, но не тогда, когда они были внутри маршрутизатора. В результате мы имеем дело с некорректной доставкой, хотя проверка на каждом канале не выявила ошибок.

Этот и другие примеры позволили ученым (Slatzer и др.) сформулировать «сквозной» принцип (end-to-end argument). Согласно этому принципу, сквозная проверка, выполняемая на транспортном уровне, является необходимой для корректной передачи данных; проверка, выполняемая на канальном уровне, не является необходимой, но позволяет существенно улучшить производительность (так как иначе поврежденный пакет будет все равно проходить весь путь, что приведет к лишней нагрузке на сеть).

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

С другой стороны, для многих TCP-соединений произведение пропускной способности и времени задержки составляет гораздо больше, чем один сегмент. Рассмотрим соединение, которое передает данные по всей территории США со скоростью 1 Мбит/с, а время, за которое пакет доходит до получателя и обратно, составляет 100 мс. Даже при таком медленном соединении 200 Кбит информации будут храниться на получателе в течение того времени, которое требуется для отправки сегмента и получения подтверждения. В таких случаях следует использовать скользящее окно большого размера. Протокол с остановкой и ожиданием подтверждения серьезно повредит производительности. В нашем примере он ограничил бы передачу одним сегментом в 200 мс (или 5 сегментами в секунду) независимо от реальной скорости сети.

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

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

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

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

Рис. 6.12. Организация набора буферов: а — цепочка буферов фиксированного размера; б — цепочка буферов переменного размера; в — один большой циклический буфер

для одного соединения

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

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

В отличие от протоколов скользящего окна, описанных в главе 3, для реализации динамического выделения буферов следует отделить буферизацию от подтверждений. Динамическое выделение буферов означает, на самом деле, использование окна переменного размера. Вначале отправитель, основываясь на своих потребностях, запрашивает определенное количество буферов. Получатель выделяет столько, сколько может. При отправлении каждого сегмента отправитель должен уменьшать на единицу число буферов, а когда это число достигнет нуля, он должен остановиться. Получатель отправляет обратно на попутных сегментах отдельно подтверждения и информацию об имеющихся у него свободных буферах. Эта схема используется в TCP; при этом информация о буферах хранится в поле заголовка Window size.

На рис. 6.13 показан пример управления динамическим окном в дейтаграммной сети с 4-битными порядковыми номерами. В этом примере данные передаются в виде сегментов от хоста A к хосту B, а подтверждения и запросы на предоставление буферов идут в обратном направлении (также в виде сегментов). Вначале хост A запрашивает 8 буферов, но ему выделяется только 4. Затем он посылает три сегмента, из которых последний теряется. На шаге 6 хост A получает подтверждение получения посланных им сегментов 0 и 1, в результате чего хост А может освободить буферы и послать еще три сегмента (с порядковыми номерами 2, 3 и 4). Хост A знает, что сегмент номер 2 он уже посылал, поэтому он думает, что может послать сегменты 3 и 4, что он и делает. На этом шаге он блокируется, так как его счетчик буферов достиг нуля и ждет предоставления новых буферов. На шаге 9 наступает тайм-аут хоста А, так как он до сих пор не получил подтверждения для сегмента 2. Этот сегмент посылается еще раз. В строке 10 хост подтверждает получение всех сегментов, включая 4-й, но отказывается предоставлять буферы хосту A. Такая ситуация невозможна в протоколах с фиксированным размером окна, описанных в главе 3. Следующий сегмент, посланный хостом B, разрешает хосту A передать еще один сегмент. Это произойдет тогда, когда у B появится свободное буферное пространство — скорее всего, потому, что потребитель транспортных услуг принял больше данных.

Рис. 6.13. Динамическое выделение буферов. Стрелками показано направление передачи. Многоточие (...) означает потерянный сегмент

Проблемы при такой схеме выделения буферов в дейтаграммных сетях могут возникнуть при потере управляющего сегмента — что действительно может произойти. Взгляните на строку 16. Хост B выделил хосту A дополнительные буферы, но сообщение об этом было потеряно. Вот так неожиданность! Поскольку получение управляющих сегментов не подтверждается и, следовательно, управляющие сегменты не посылаются повторно по тайм-ауту, хост A теперь оказался блокированным всерьез и надолго. Для предотвращения такой тупиковой ситуации каждый хост должен периодически посылать управляющий сегмент, содержащий подтверждение и состояние буферов для каждого соединения. Это позволит, в конце концов, выбраться из тупика.

До сих пор мы по умолчанию предполагали, что единственное ограничение, накладываемое на скорость передачи данных, состоит в количестве свободного буферного пространства у получателя. Однако часто это бывает не так. По мере колоссального снижения цен (некогда очень высоких) на микросхемы памяти и винчестеры становится возможным оборудовать хосты таким количеством памяти, что проблема нехватки буферов будет возникать очень редко, если вообще будет возникать, даже если соединение охватывает крупные территории. Конечно же, необходимо, чтобы выбранный размер буфера был достаточно большим; это требование не всегда выполнялось в случае TCP (Zhang и др., 2002).

Если размер буферов перестанет ограничивать максимальный поток, возникнет другое узкое место: пропускная способность сети. Если максимальная скорость обмена кадрами между соседними маршрутизаторами будет x кадров в секунду и между двумя хостами имеется k непересекающихся путей, то, сколько бы ни было буферов у обоих хостов, они не смогут пересылать друг другу больше, чем kx сегментов в секунду. И если отправитель будет передавать с большей скоростью, то сеть окажется перегруженной.

Требуется механизм, который мог бы ограничивать передачу данных со стороны отправителя и основывался не столько на емкости буферов получателя, сколько на пропускной способности сети. В 1975 году Белснес (Belsnes) предложил использовать для управления потоком данных схему скользящего окна, в которой отправитель динамически приводит размер окна в соответствие с пропускной способностью сети. Таким образом, скользящее окно позволяет одновременно реализовать и управление потоком, и контроль перегрузки. Если сеть может обработать c сегментов в секунду, а время цикла (включая передачу, распространение, ожидание в очередях, обработку получателем и возврат подтверждения) равно г, тогда размер окна отправителя должен быть равен cr. При таком размере окна отправитель работает, максимально используя канал. Любое уменьшение производительности сети приведет к его блокировке. Так как пропускная способность сети меняется с течением времени, размер окна должен настраиваться довольно часто, чтобы можно было отслеживать изменения пропускной способности. Как будет показано ниже, в TCP используется похожая схема.

6.2.5. Мультиплексирование

Объединение нескольких разговоров в одном соединении, виртуальном канале и по одной физической линии играет важную роль в нескольких уровнях сетевой архитектуры. Потребность в подобном уплотнении возникает в ряде случаев и на транспортном уровне. Например, если у хоста имеется только один сетевой адрес, он используется всеми соединениями транспортного уровня. Нужен какой-то способ, с помощью которого можно было бы различать, какому процессу следует передать входящий сегмент. Такая ситуация, называемая мультиплексированием, показана на рис. 6.14, а. На рисунке четыре различных соединения транспортного уровня используют одно сетевое соединение (например, один IP-адрес) с удаленным хостом.

Рис. 6.14. Мультиплексирование: а — прямое; б — обратное мультиплексирование

Уплотнение может играть важную роль на транспортном уровне и по другой причине. Предположим, например, что хост может использовать несколько различных сетевых путей. Если пользователю требуется большая пропускная способность или большая надежность, нежели может предоставить один сетевой путь, то можно попробовать решить эту проблему путем открытия соединения, распределяющего трафик между путями, используя их поочередно, как показано на рис. 6.14, б. Такой метод называется обратным мультиплексированием. При k открытых сетевых соединениях эффективная пропускная способность может увеличиться в k раз. Примером обратного мультиплексирования является SCTP (Stream Control Transmission Protocol протокол передачи с управлением потоками), позволяющий устанавливать соединение с множественными сетевыми интерфейсами. TCP, наоборот, использует отдельный сокет. Обратное мультиплексирование используется и на канальном уровне — при этом несколько медленных каналов связи объединяются в один, работающий гораздо быстрее.

6.2.6. Восстановление после сбоев

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

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

Пытаясь восстановить предыдущее состояние, сервер может разослать широковещательный сегмент всем хостам, объявляя им, что он только что перезагрузился, и прося своих клиентов сообщить ему о состоянии всех открытых соединений. Каждый клиент может находиться в одном из двух состояний: один неподтвержденный сегмент (состояние S1) или ни одного неподтвержденного сегмента (состояние S0). Этой информации клиенту должно быть достаточно, чтобы решить, передавать ему повторно последний сегмент или нет.

На первый взгляд, здесь все очевидно: узнав о перезапуске сервера, клиент должен передать повторно последний неподтвержденный сегмент. То есть повторная передача требуется тогда и только тогда, когда клиент находится в состоянии S1. Однако при более детальном рассмотрении оказывается, что все не так просто, как мы наивно предположили. Рассмотрим, например, ситуацию, в которой транспортная подсистема сервера сначала посылает подтверждение, а уже затем передает пакет прикладному процессу. Запись сегмента в выходной поток и отправка подтверждения являются двумя различными неделимыми событиями, которые не могут быть выполнены одновременно. Если сбой произойдет после отправки подтверждения, но до того как выполнена запись, клиент получит подтверждение, а при получении объявления о перезапуске сервера окажется в состоянии S0. Таким образом, клиент не станет передавать сегмент повторно, так как будет считать, что сегмент уже получен, что в конечном итоге приведет к отсутствию сегмента.

В этом месте вы, должно быть, подумаете: «А что если поменять местами последовательность действий, выполняемых транспортной подсистемой сервера, чтобы сначала осуществлялась запись, а потом высылалось подтверждение?» Представим, что запись сделана, но сбой произошел до отправки подтверждения. В этом случае клиент окажется в состоянии S1 и поэтому передаст сегмент повторно, и мы получим дубликат сегмента в выходном потоке.

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

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

На сервере могут происходить три события: отправка подтверждения (А), запись сегмента в выходной процесс (W) и сбой (С). Они могут произойти в виде шести возможных последовательностей: АС( W), AWC, C(AW), C(WA), WAC и WC(A), где скобки означают, что после события С событие А или B может и не произойти (то есть уж сломался, так сломался). На рис. 6.15 показаны все восемь комбинаций стратегий сервера и клиента, каждая со своими последовательностями событий. Обратите внимание, что для каждой комбинации существует последовательность событий, приводящая к ошибке протокола. Например, если клиент всегда передает повторно неподтвержденный сегмент, событие AWC приведет к появлению неопознанного дубликата, хотя при двух других последовательностях событий протокол будет работать правильно.

Рис. 6.15. Различные комбинации стратегий сервера и клиента

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

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

Эта проблема подводит нас к вопросу о значении так называемого сквозного подтверждения. В принципе, транспортный протокол является сквозным, а не цепным, как более низкие уровни. Теперь рассмотрим случай обращения пользователя к удаленной базе данных. Предположим, что удаленная транспортная подсистема запрограммирована сначала передавать сегмент вышестоящему уровню, а затем отправлять подтверждение. Даже в этом случае получение подтверждения машиной пользователя не означает, что удаленный хост успел обновить базу данных. Настоящее сквозное подтверждение, получение которого означает, что работа была сделана, и, соответственно, отсутствие которого означает обратное, вероятно, невозможно. Более подробно этот вопрос обсуждается в (Saltzer и др., 1984).

6.3. Контроль перегрузки

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

В главе 5 мы говорили о механизмах контроля перегрузки на сетевом уровне. В этом разделе мы расскажем о другой части этого процесса — механизмах контроля перегрузки на транспортном уровне. После обсуждения основных задач контроля перегрузки мы перейдем к описанию методов, позволяющих хостам регулировать скорость передачи пакетов в сеть. Контроль перегрузки в сети Интернет опирается во многом на транспортный уровень; для этого в TCP и другие протоколы встроены специальные алгоритмы.

6.3.1. Выделение требуемой пропускной способности

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

Эффективность и мощность

Эффективное распределение пропускной способности между транспортными подсистемами должно использовать все возможности сети. Однако это не значит, что в случае канала со скоростью 100 Мбит/с каждая из пяти транспортных подсистем должна получить по 20 Мбит/с. Для хорошей производительности им необходимо выделить меньшую мощность. Причина в том, что трафик часто бывает неравномерным. В разделе 5.3 мы определили эффективную пропускную способность (goodput, скорость, с которой полезные пакеты прибывают к получателю) как функцию нагрузки на сеть. Эта кривая и соответствующая ей кривая задержки (как функция нагрузки) приведены на рис. 6.16.

Рис. 6.16. Эффективная пропускная способность (а); задержка как функции нагрузки (б)

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

График задержки пакетов приведен на рис. 6.16, б. Сначала задержка является постоянной и соответствует задержке распространения в сети. Когда значение нагрузки приближается к значению пропускной способности, задержка возрастает, причем сначала медленно, а затем все быстрее и быстрее. Это происходит опять же из-за всплесков трафика, которые возрастают при высокой нагрузке. В действительности задержка не может уходить в бесконечность, если только модель не предполагает использование бесконечных буферов. Вместо этого пакеты будут теряться при переполнении буферов.

Для достижения хорошей эффективной пропускной способности и задержки производительность должна начать снижаться в момент возникновения перегрузки. Логично, что для достижения лучшей производительности сети можно выделять пропускную способность до тех пор, пока задержка не пойдет резко вверх. Эта точка находится ниже пропускной способности сети. Чтобы ее определить, Кляйнрок (Klein-rock) в 1979 году предложил ввести метрику мощность (power), которая вычисляется по формуле:

мощность = нагрузка/задержка.

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

Равнодоступность по максиминному критерию

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

Во-первых, зададимся вопросом: какое отношение эта проблема имеет к контролю нагрузки? В конце концов, если сеть предоставляет отправителю некоторое количество пропускной способности, он должен просто использовать то, что у него есть. Однако на практике сети часто не резервируют строго ограниченное количество пропускной способности для потока или соединения. Конечно, для некоторых потоков они могут это делать (если есть поддержка качества обслуживания), но, как правило, многие соединения стремятся использовать максимум доступной пропускной способности; также возможен вариант, при котором сеть выделяет ресурсы для совместного использования группой соединений. К примеру, дифференцированное обслуживание IETF разделяет трафик на два класса, и соединения конкурируют друг с другом в пределах каждого из этих классов. Часто все соединения одного IP-маршрутизатора используют общую пропускную способность. В таких случаях распределение пропускной способности между конкурирующими соединениями должно осуществляться за счет механизмов контроля нагрузки.

Во-вторых, не совсем ясно, что такое равноправие потоков в сети. Если N потоков используют один канал, то решение довольно просто: каждому из них выделяется 1/N пропускной способности (в случае импульсного трафика эта величина по соображениям эффективности будет немного меньше). Но что если потоки используют разные, но пересекающиеся пути? К примеру, если один поток проходит по трем каналам, а остальные потоки — по одному? Очевидно, что поток, проходящий по трем каналам, потребляет больше сетевых ресурсов. Поэтому в некотором смысле справедливее было бы выделить ему меньше пропускной способности, чем остальным потокам (проходящим по одному каналу). Кроме того, неплохо было бы обеспечить возможность добавления новых одноканальных потоков за счет уменьшения пропускной способности трехканального. Как показывает этот пример, между равноправием и эффективностью всегда существуют противоречия.

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

Часто в сетях удобнее использовать форму равноправия, которая называется равнодоступностью по максиминному критерию. Это значит, что увеличение пропускной способности одного потока невозможно без уменьшения пропускной способности какого-либо другого потока с меньшей или равной пропускной способностью. Иными словами, от увеличения пропускной способности потока страдают менее «обеспеченные» потоки.

Рассмотрим пример. На рис. 6.17 показано распределение пропускной способности по максиминному критерию в сети с четырьмя потоками A, B, C и D. Все каналы, соединяющие маршрутизаторы, обладают одинаковой пропускной способностью, принятой за 1 (хотя на практике это обычно не так). На пропускную способность канала, расположенного слева внизу (между маршрутизаторами R4 и R5), претендуют три потока. Поэтому каждый из них получает по 1/3. Оставшийся поток, A, конкурирует с B на участке от R2 до R3. Поскольку для B уже выделена 1/3 пропускной способности канала, A получает оставшееся количество, 2/3. Как видно из рисунка, на остальных каналах часть пропускной способности не используется. Но эти ресурсы нельзя отдать какому-либо потоку, не снизив пропускную способность другого, более медленного потока. К примеру, если на участке от R2 до R3 выделить потоку B больше пропускной способности, то потоку A достанется меньше. Это логично, поскольку на данный момент у A пропускной способности больше. Но для того чтобы обеспечить большую пропускную способность для потока B, придется снизить пропускную способность C или D (или обоих), и тогда его (или их) пропускная способность станет меньше пропускной способности B. Таким образом, данное распределение соответствует максиминному критерию.

Рис. 6.17. Распределение пропускной способности по максиминному критерию

для четырех потоков

Распределение пропускной способности по максиминному критерию можно вычислить на основе данных обо всей сети. Чтобы наглядно это себе представить, предположим, что скорость всех потоков медленно возрастает, начиная от 0. Как только у одного из потоков возникает узкое место, его скорость перестает расти. Далее скорость остальных потоков продолжает увеличиваться (при этом доступная пропускная способность делится поровну), пока каждый из них не дойдет до своего узкого места.

В-третьих, не очень понятно, на каком уровне рассматривать равноправие. Сеть может обеспечивать равноправие потоков на уровне соединений, соединений между парой хостов или всех соединений одного хоста. Эту проблему мы обсуждали, когда говорили о взвешенном справедливом обслуживании (см. раздел 5.4): выяснилось, что с каждым из этих вариантов связаны определенные трудности. К примеру, если считать равноправными все хосты, активно работающий сервер будет получать не больше ресурсов, чем обычный мобильный телефон; если же равноправными считать все соединения, хостам будет выгодно открывать дополнительные новые соединения. Поскольку на этот вопрос нет однозначного ответа, равноправие часто рассматривается применительно к соединениям, однако такое равноправие совсем не обязано быть точным. В первую очередь важно, чтобы ни одно соединение не осталось без пропускной способности. На самом деле, TCP позволяет открывать множественные соединения, что вызывает более жесткую конкуренцию. Эта тактика подходит для приложений, особенно требовательных к возможностям сети. Например, ее использует BitTorrent для однорангового совместного использования файлов.

Сходимость

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

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

На рис. 6.18 показан пример распределения пропускной способности, которая изменяется со временем и быстро сходится. Изначально поток 1 получает всю пропускную способность. Через секунду начинает работать поток 2. Ему тоже нужна пропускная способность. Поэтому распределение быстро меняется, так чтобы оба потока получали по 1/2. Еще через три секунды появляется третий поток. Но он использует только 20 % пропускной способности — меньше, чем то, что ему полагается исходя из идеи равноправия (1/3). Потоки 1 и 2 быстро реагируют на изменение ситуации, и каждый из них получает 40 %. В момент времени 9 с второй поток отключается, а третий продолжает работать без изменений. Поток 1 быстро занимает 80 % пропускной способности. В каждый момент времени суммарная пропускная способность приблизительно равна 100 %, то есть возможности сети используются полностью; при этом все конкурирующие потоки оказываются в равных условиях (но не используют больше пропускной способности, чем им нужно).

Рис. 6.18. Изменение распределения пропускной способности с течением времени

6.3.2. Регулирование скорости отправки

Теперь самое время перейти к основному вопросу: как можно регулировать скорость отправки, чтобы получить необходимую пропускную способность? Скорость отправки может зависеть от двух факторов. Первый из них — управление потоком данных, которое требуется, если буфер получателя обладает недостаточной емкостью. Второй фактор — перегрузка, которую необходимо учитывать при недостаточной пропускной способности сети. На рис. 6.19 эта проблема проиллюстрирована на примере водопровода. На рис. 6.19, а мы видим толстую трубу, ведущую к получателю с небольшой емкостью. Это тот случай, когда ограничительным фактором является управление потоком данных. До тех пор пока отправитель не посылает воды больше, чем может поместиться в ведро, вода не будет проливаться. На рис. 6.29, б ограничительным фактором является не емкость ведра, а пропускная способность сети. Если из крана в воронку вода будет литься слишком быстро, то уровень воды в воронке начнет подниматься, и, в конце концов, часть воды может перелиться через край воронки.

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

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

Пример явной точной обратной связи — ситуация, когда маршрутизаторы сообщают источникам свою допустимую скорость отправки. Так работает, к примеру, XCP (eXplicit Congestion Protocol) (Katabi и др., 2002). Явная и неточная схема — использование ECN (Explicit Congestion Notification, явное уведомление о насыщении) с TCP. В этом случае маршрутизаторы специальным образом маркируют пакеты, страдающие от перегрузки, и таким образом сообщают отправителю, что ему следует уменьшить скорость передачи данных, не указывая при этом, насколько сильно ее нужно уменьшить.

Рис. 6.19. Быстрая сеть и получатель малой емкости (а); медленная сеть и получатель большой емкости (б)

В других схемах явный сигнал отсутствует. FAST TCP измеряет круговую задержку и использует ее в качестве параметра для контроля перегрузки (Wei и др., 2006). Наконец, метод контроля перегрузки, наиболее распространенный в современном Интернете, использует TCP и маршрутизаторы с отбрасыванием конца очереди или маршрутизаторы со случайным ранним обнаружением перегрузки. Показателем перегрузки сети в нем является число потерянных пакетов. Существует множество вариантов этого вида TCP — в частности, CUBIC TCP, использующийся в системе Linux (Ha и др., 2008). Возможны также комбинации нескольких методов. К примеру, Windows включает Compound TCP (составной TCP), в котором показателями насыщения являются и круговая задержка, и число потерянных пакетов (Tan и др., 2006). Эти схемы показаны в табл. 6.3.

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

Таблица 6.3. Сигналы некоторых протоколов контроля насыщения

Протокол

Сигнал

Явный?

Точный?

XCP

Скорость, которую следует использовать

Да

Да

TCP с ECN

Предупреждение о перегрузке

Да

Нет

FAST TCP

Сквозная задержка

Нет

Да

Compound TCP

Потеря пакетов и сквозная задержка

Нет

Да

CUBIC TCP

Потеря пакетов

Нет

Нет

TCP

Потеря пакетов

Нет

Нет

Рассматривая бинарный признак насыщения, Chiu и Jain (1989) пришли к выводу, что закон управления AIMD (Additive Increase Multiplicative Decrease аддитивное увеличение мультипликативное уменьшение) позволяет эффективно вычислять рабочий режим с учетом идеи равнодоступности. Чтобы это показать, они привели простой наглядный пример, в котором два соединения соперничают друг с другом за пропускную способность общего канала. На рис. 6.20 пропускная способность, выделяемая пользователю 1, располагается на оси X, а пропускная способность, выделяемая пользователю 2, — на оси Y. При справедливом распределении оба пользователя получают одинаковое количество пропускной способности. Таким распределениям соответствует прямая равноправия, изображенная пунктиром. Когда суммарная пропускная способность, выделяемая всем пользователям, составляет 100 % (то есть равна пропускной способности канала), распределение является эффективным. Эффективные распределения располагаются на прямой эффективности. Когда суммарная пропускная способность пересекает эту прямую, оба пользователя получают сигнал о насыщении. Точка пересечения этих прямых соответствует оптимальному рабочему режиму, при котором пользователи получают одинаковое количество пропускной способности и используется вся пропускная способность сети.

Рис. 6.20. Аддитивное и мультипликативное регулирование пропускной способности

Пусть изначально пользователю 1 и пользователю 2 выделено некоторое количество пропускной способности. Посмотрим, что произойдет, если оба пользователя начнут аддитивно увеличивать свою пропускную способность. К примеру, они могут повышать скорость отправки пакетов на 1 Мбит/с каждую секунду. В результате рабочий режим пересечет прямую эффективности, и оба пользователя получат сигнал о насыщении сети. В этот момент им придется снизить используемую пропускную способность. Однако аддитивное уменьшение попросту приведет к колебаниям значений вдоль аддитивной прямой (см. рис. 6.20). В результате рабочий режим будет оставаться близким к эффективному, однако он не обязательно будет справедливым.

Рассмотрим аналогичную ситуацию, в которой оба пользователя увеличивают свою пропускную способность мультипликативно до тех пор, пока не поступит сигнал о насыщении сети. Например, они могут каждую секунду повышать скорость отправки пакетов на 10 %. Если после получения сигнала о насыщении пользователи будут уменьшать пропускную способность мультипликативно, рабочий режим будет колебаться вдоль мультипликативной прямой (см. рис. 6.20). Наклон мультипликативной прямой отличается от наклона аддитивной прямой. (Мультипликативная прямая проходит через начало координат, а аддитивная имеет наклон 45°.) Однако это ничего нам не дает. Ни в том, ни в другом случае оптимальная скорость отправки не будет достигнута.

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

Рис. 6.21. Закон управления AIMD

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

В разделе 6.5 мы подробно поговорим о том, как с помощью закона управления AIMD в TCP осуществляется регулировка скорости отправки пакетов и контроль перегрузки. Эта задача гораздо сложнее, чем может показаться. Проблемы возникают из-за того, что значения скорости измеряются через определенный интервал времени, а трафик, как правило, бывает импульсным. На практике вместо скорости отправки пакетов часто задается размер скользящего окна. Такая стратегия используется и в TCP. Если размер окна равен W, а круговая задержка — RTT, то эквивалентная скорость равна W/RTT. Это удобно, поскольку управление потоком данных также основано на регулировке размера окна. Кроме того, такой метод обладает важным преимуществом: если подтверждения о доставке пакетов перестанут приходить, через время RTT скорость отправки уменьшится.

Наконец, иногда в одной сети используются разные транспортные протоколы. Что произойдет, если эти протоколы будут одновременно пытаться контролировать перегрузку с помощью разных законов управления? Ответ очевиден: распределение пропускной способности не будет справедливым. Поскольку самой распространенной формой контроля перегрузки в сети Интернет является TCP, новые транспортные протоколы настоятельно рекомендуется разрабатывать так, чтобы при совместной работе с TCP выполнялось условие справедливого распределения ресурсов. Использовавшиеся ранее протоколы потокового вещания не соответствовали этому требованию, существенно уменьшая пропускную способность TCP. В результате стала развиваться идея дружественного к TCP контроля перегрузки, при котором транспортные протоколы TCP и не-TCP могут работать вместе, не мешая друг другу (Floyd и др., 2000).

6.3.3. Проблемы беспроводного соединения

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

Если протокол использует закон управления AIMD, большая пропускная способность требует минимальной потери пакетов. Исследования Padhye и др. (1998) показали, что пропускная способность растет обратно пропорционально квадратному корню из скорости потери пакетов. На практике это означает, что скорость потери пакетов для быстрых TCP-соединений очень мала; в среднем этот показатель составляет 1 %, а при значении 10 % соединение перестает работать. Однако для беспроводных сетей, таких как локальная сеть 802.11, вполне обычными являются значения скорости потери кадров порядка 10 % и выше. Если этого не учитывать, схемы контроля перегрузки, использующие в качестве сигнала насыщения потерю пакетов, попросту «задушат» беспроводные соединения, крайне ограничив их скорость.

Чтобы такой алгоритм контроля перегрузки работал правильно, он должен учитывать только те потери пакетов, которые произошли из-за недостатка пропускной способности, а не из-за ошибок передачи. Одно из возможных решений — скрыть потерю данных с помощью их повторной передачи по беспроводным каналам. К примеру, в 802.11 для доставки каждого кадра используется протокол с остановкой и ожиданием подтверждения: передача кадра повторяется несколько раз, и только после этого информация о потере пакета поступает на более высокий уровень. В большинстве случаев пакеты доставляются на место назначения, несмотря на ошибки передачи (о которых более высокие уровни ничего не знают).

На рис. 6.22 показан путь по проводному и беспроводному каналу, для которого используется эта стратегия. Здесь следует обратить внимание на два аспекта. Во-первых, отправитель не знает о том, что путь содержит беспроводной канал, так как все, что он видит, — это проводной канал, к которому он непосредственно подсоединен. В сети Интернет пути являются гетерогенными, однако не существует универсального способа, позволяющего отправителю определить, из каких каналов состоит путь. Это осложняет проблему контроля перегрузки, поскольку использовать разные протоколы для проводных и беспроводных каналов — очень непростая задача.

Рис. 6.22. Контроль перегрузки для пути, содержащего беспроводной канал

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

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

Такая стратегия необходима для нормальной работы большинства транспортных протоколов с большинством беспроводных каналов. Однако существуют ситуации, для которых это решение не подходит. Некоторые беспроводные каналы — например, спутниковые — обладают большой круговой задержкой. В таких случаях требуются другие методы, позволяющие скрыть потерю пакетов, — такие, как FEC (Forward Error Correction упреждающая коррекция ошибок); или же транспортный протокол должен использовать сигналы без потерь для контроля перегрузки.

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

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

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

6.4. Транспортные протоколы Интернета: UDP

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

В следующих разделах мы изучим UDP и TCP. Так как UDP проще, его мы изучим первым. Мы также рассмотрим два практических применения UDP. Поскольку протокол транспортного уровня UDP обычно запускается в операционной системе, а протоколы, использующие UDP, — в пространстве пользователя, эти применения вполне можно считать приложениями. Однако методы, которые в них используются, оказываются полезными для многих приложений и их лучше считать частью транспортного сервиса. Поэтому о них мы тоже поговорим.

6.4.1. Основы UDP

Среди набора протоколов Интернета есть транспортный протокол без установления соединения, UDP (User Datagram Protocol — протокол передачи дейтаграмм пользователя). UDP позволяет приложениям отправлять инкапсулированные IP-дейтаграммы без установления соединений. UDP описан в RFC 768.

С помощью протокола UDP передаются сегменты, состоящие из 8-байтного заголовка, за которым следует поле полезной нагрузки. Заголовок показан на рис. 6.23. Два номера портов служат для идентификации сокетов внутри отправляющей и принимающей машин. Когда прибывает пакет UDP, содержимое его поля полезной нагрузки передается процессу, связанному с портом назначения. Это связывание происходит при выполнении базовой операции типа BIND. Это было продемонстрировано в листинге 6.1 применительно к TCP (в UDP процесс связывания происходит точно так же). Представьте себе, что порты — это почтовые ящики, арендуемые приложениями. Мы поговорим о них подробнее при обсуждении TCP, который тоже использует порты. В сущности, весь смысл использования UDP вместо обычного IP заключается как раз в указании портов источника и приемника. Без этих двух полей на транспортном уровне невозможно было бы определить действие, которое следует производить с каждым входящим пакетом. В соответствии с полями портов производится доставка вложенных сегментов соответствующим приложениям.

Рис. 6.23. Заголовок UDP

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

Поле Длина UDP состоит из заголовка и данных. Минимальная длина равна длине заголовка, то есть 8 байтам. Максимальная длина равна 65 515 байтам — это меньше, чем максимальное число, записывающееся с помощью 16 бит, из-за ограничений на размер IP-пакета.

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

В случае IPv4 псевдозаголовок будет выглядеть так, как показано на рис. 6.24. Он содержит 32-разрядные IP-адреса отправителя и получателя, номер протокола для UDP (17) и счетчик байтов для UDP-сегмента (включая заголовок). Включение псевдозаголовка в контрольную сумму UDP помогает обнаружить неверно доставленные пакеты, хотя это нарушает иерархию протоколов, так как IP-адреса в нем принадлежат IP-уровню, а не UDP-уровню. В TCP для контрольной суммы используется такой же псевдозаголовок.

Рис. 6.24. Псевдозаголовок, включаемый в контрольную сумму UDP

Наверное, стоит прямо сказать о том, чего UDP не делает. Итак, UDP не занимается управлением потоком данных, контролем перегрузки, повторной передачей после приема испорченного сегмента. Все это перекладывается на пользовательские процессы. Что же он делает? UDP предоставляет интерфейс для IP путем демультиплексирования нескольких процессов с использованием портов и необязательного сквозного обнаружения ошибок. Это все, что он делает.

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

DNS (Domain Name System — служба имен доменов) — это приложение, которое использует UDP именно так, как описано выше. Мы изучим его в главе 7. В двух словах, если программе нужно найти IP-адрес по имени хоста, например www.cs.berkeley. edu, она может послать UDP-пакет с этим именем на сервер DNS. Сервер в ответ на запрос посылает UDP-пакет с IP-адресом хоста. Никакой предварительной настройки не требуется, как не требуется и разрыва соединения после завершения задачи. По сети просто передаются два сообщения.

6.4.2. Вызов удаленной процедуры

В определенном смысле процессы отправки сообщения на удаленный хост и получения ответа очень похожи на вызов функции в языке программирования. В обоих случаях необходимо передать один или несколько параметров, и вы получаете результат. Это соображение навело разработчиков на мысль о том, что можно попробовать организовать запросно-ответное взаимодействие по сети, выполняемое в форме вызовов процедур. Такое решение позволяет упростить и сделать более привычной разработку сетевых приложений. Например, представьте себе процедуру с именем 9et_IP_address(^_xocTa), работающую посредством отправки UDP-пакетов на сервер DNS, ожидания ответа и отправки повторного запроса в случае наступления таймаута (если одна из сторон работает недостаточно быстро). Таким образом, все детали, связанные с особенностями сетевых технологий, скрыты от программиста.

Ключевая работа в этой области написана в 1984 году Бирреллом (Birrell) и Нельсоном (Nelson). По сути дела, было предложено разрешить программам вызывать процедуры, расположенные на удаленных хостах. Когда процесс на машине 1 вызывает процедуру, находящуюся на машине 2, вызывающий процесс машины 1 блокируется, и выполняется вызванная процедура на машине 2. Информация от вызывающего процесса может передаваться в виде параметров и приходить обратно в виде результата процедуры. Передача сообщений по сети скрыта от программиста приложения. Такая технология известна под названием RPC (Remote Procedure Call удаленный вызов процедур) и стала основой многих сетевых приложений. Традиционно вызывающая процедура считается клиентом, а вызываемая — сервером. Мы и здесь будем называть их так же.

Идея RPC состоит в том, чтобы сделать вызов удаленной процедуры максимально похожим на локальный вызов. В простейшем случае для вызова удаленной процедуры клиентская программа должна быть связана с маленькой библиотечной процедурой, называемой клиентской заглушкой (client stub), которая отображает серверную процедуру в пространство адресов клиента. Аналогично сервер должен быть связан с процедурой, называемой серверной заглушкой (server stub). Эти процедуры скрывают тот факт, что вызов клиентом серверной процедуры осуществляется не локально.

Реальные шаги, выполняемые при удаленном вызове процедуры, показаны на рис. 6.25. Шаг 1 заключается в вызове клиентом клиентской заглушки. Это локальный вызов процедуры, параметры которой самым обычным образом помещаются в стек. Шаг 2 состоит в упаковке параметров клиентской заглушки в сообщение и в осуществлении системного вызова для отправки этого сообщения. Упаковка параметров называется маршалингом (marshaling). На шаге 3 операционная система передает

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

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

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

Рис. 6.25. Этапы выполнения удаленного вызова процедуры. Заглушки затенены

Иногда с помощью некоторых уловок все же удается передавать указатели. Допустим, первым параметром является указатель на целое число k. Клиентская заглушка может выполнить маршалинг k и передать его серверу. Серверная заглушка создаст указатель на полученную переменную k и передаст его серверной процедуре. Именно этого та и ожидала. Когда серверная процедура возвращает управление серверной заглушке, последняя отправляет k обратно клиенту, где обновленное значение этой переменной записывается вместо старого (если оно было изменено сервером). В принципе, стандартная последовательность действий, выполняемая при передаче параметра по ссылке, заменилась прямой и обратной передачей копии параметра. Увы, этот трюк не всегда удается применить — в частности, нельзя это сделать, если указатель ссылается на граф или иную сложную структуру данных. Как мы увидим далее, по этой причине на параметры удаленно вызываемых процедур должны быть наложены определенные ограничения.

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

Третья проблема заключается в том, что не всегда можно распознать типы параметров по спецификации или по самому коду. В качестве примера можно привести процедуру printf, у которой может быть любое число параметров (не меньше одного), и они могут представлять собой смесь различных целочисленных (int, short, long), символьных, строковых, вещественных с плавающей запятой различной длины и других типов. Задача удаленного вызова процедуры printf может оказаться практически невыполнимой из-за такой своеобразной толерантности языка С. Тем не менее нет правила, говорящего, что удаленный вызов процедур возможен только в том случае, если используется не С (C++), — это подорвало бы репутацию метода RPC среди программистов.

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

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

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

Проблема более высокого уровня связана с тем, что операция может не быть идемпотентной (то есть не может повторяться без риска сбоя). В простом случае мы имеем дело с идемпотентными операциями, такими как DNS-запросы и ответы. Клиент может повторно без риска передавать такие пакеты сколько угодно раз, до тех пор пока не придет ответ. Не важно, в чем причина: либо пакет не дошел до сервера, либо был потерян ответ. В любом случае ответ, когда он придет, будет одним и тем же (если, конечно, за это время не обновится база данных DNS). Однако не все операции идемпотентны — например, потому, что они могут включать побочные действия наподобие инкрементирования счетчика. RPC для таких операций требует более сложной семантики: при вызове процедуры она не должна выполняться несколько раз. В таких случаях может понадобиться установка TCP-соединения и отправки запроса по TCP, а не по UDP.

6.4.3. Транспортные протоколы реального масштаба времени

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

Так появился на свет протокол RTP (Real-Time Transport Protocol — транспортный протокол реального масштаба времени). Он описан в RFC 3550 и ныне широко используется для мультимедийных приложений. Мы рассмотрим два аспекта транспортировки данных в реальном времени. Первый из них — протокол RTP, использующийся для пакетной передачи аудио и видео. Второй аспект — обработка данных, необходимая для воспроизведения (в основном со стороны получателя). Эти функции входят в стек протоколов, изображенный на рис. 6.26.

RTP обычно работает поверх UDP (в операционной системе). Делается это так. Мультимедийное приложение может состоять из нескольких аудио-, видео-, текстовых и некоторых других потоков. Они прописываются в библиотеке RTP, которая, как и само приложение, находится в пользовательском пространстве. Библиотека уплотняет потоки и помещает их в пакеты RTP, которые, в свою очередь, отправляются в сокет. На другом конце сокета (в операционной системе) генерируются UDP-пакеты, в которые помещаются RTP-пакеты. Они передаются протоколу IP для отправки по каналу (например, Ethernet). На хосте-получателе происходит обратный процесс. В конечном итоге мультимедийное приложение получает данные из RTP-библиотеки. Оно отвечает за воспроизведение мультимедиа. Стек протоколов для описанной ситуации показан на рис. 6.26, а. Система вложенных пакетов показана на рис. 6.26, б.

В результате оказывается непросто определить, к какому уровню относится RTP. Так как протокол работает в пользовательском пространстве и связан с прикладной программой, он, несомненно, выглядит, как прикладной протокол. С другой стороны, он является общим, независимым от приложения протоколом, который просто предоставляет транспортные услуги, не более. С этой точки зрения он может показаться транспортным протоколом. Наверное, лучше всего будет определить его таким образом: RTP — это транспортный протокол, который случайно оказался на прикладном уровне, и именно поэтому мы говорим о нем в этой главе.

Рис. 6.26. RTR: а — положение RTP в стеке протоколов; б — вложение пакетов

RTP — транспортный протокол реального масштаба времени

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

Формат RTP обладает рядом особенностей, которые помогают получателям обрабатывать мультимедийные данные. Каждый пакет, посылаемый с потоком RTP, имеет номер, на единицу превышающий номер своего предшественника. Такой способ нумерации позволяет получателю определить пропажу пакетов. Если обнаруживается исчезновение какого-либо пакета, то выбор оптимального для получателя решения остается за приложением. Если пакеты содержат видеоданные, возможен пропуск потерянных кадров. В случае аудиоданных можно путем интерполяции аппроксимировать пропущенное значение. Повторная передача в данном случае не является хорошим решением, поскольку это займет много времени, и повторно переданный пакет окажется уже никому не нужным. Поэтому в протоколе RTP не предусмотрено никаких подтверждений и механизмов запроса повторной передачи.

В поле полезной нагрузки RTP может содержаться несколько элементов данных, которые могут иметь формат, соответствующий отправившему их приложению. Межсетевое взаимодействие обеспечивается в протоколе RTP за счет определения нескольких профилей (например, отдельных аудиопотоков), каждому из которых может сопоставляться несколько форматов кодирования. Скажем, аудиопоток может кодироваться при помощи PCM (8-битными символами с полосой 8 кГц), дельтакодирования, кодирования с предсказанием, GSM-кодирования, MP3-кодирования и т. д. В RTP имеется специальное поле заголовка, в котором источник может указать метод кодирования, однако далее источник никак не влияет на процесс кодирования.

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

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

Заголовок RTP показан на рис. 6.27. Он состоит из трех 32-разрядных слов и некоторых возможных расширений. Первое слово содержит поле Версия, которое в настоящий момент уже имеет значение 2. Будем надеяться, что текущая версия окажется окончательной или хотя бы предпоследней, поскольку в идентифицирующем ее двухбитном поле осталось место только для одного нового номера (впрочем, код 3 может обозначать, что настоящий номер версии содержится в поле расширения).

Рис. 6.27. Заголовок RTP

Бит P указывает на то, что размер пакета сделан кратным 4 байтам за счет байтов заполнения. При этом в последнем байте заполнения содержится общее число байтов заполнения. Бит Х говорит о том, что присутствует расширенный заголовок. Формат и назначение расширенного заголовка не определяются. Обязательным для него является только то, что первое слово расширения должно содержать общую длину расширения. Это запасная возможность для разнообразных непредсказуемых будущих требований.

Поле СС говорит о том, сколько сотрудничающих источников формируют поток. Их число может колебаться от 0 до 15 (см. ниже). Бит М — это маркер, связанный с конкретным приложением. Он может использоваться для обозначения начала видеокадра, начала слова в аудиоканале или еще для чего-нибудь, важного и понятного для приложения. Поле Тип данных содержит информацию об использующемся алгоритме кодирования (например, несжатое 8-битное аудио, MP3 и т. д.). Поскольку такое поле есть в каждом пакете, метод кодирования может изменяться прямо во время передачи потока. Порядковый номер — это просто счетчик, который инкрементируется в каждом пакете RTP. Он используется для определения потерявшихся пакетов.

Метка времени генерируется источником потока и служит для записи момента создания первого слова пакета. Отметки времени помогают снизить эффект временных колебаний, или джиттера, на приемнике за счет того, что момент воспроизведения делается независимым от времени прибытия пакета. Идентификатор источника синхронизации позволяет определить, какому потоку принадлежит пакет. Это и есть применяемый метод мультиплексирования и демультиплексирования нескольких потоков данных, следующих в виде единого потока UDP-пакетов. Наконец, Идентификаторы сотрудничающих источников, если таковые имеются, используются, когда конечный поток формируется несколькими источниками. В этом случае микширующее устройство является источником синхронизации, а в полях идентификаторов источников перечисляются смешиваемые потоки.

RTCP — управляющий транспортный протокол реального времени

У протокола RTP есть небольшой родственный протокол под названием RTCP (RealTime Transport Control Protocol управляющий транспортный протокол реального времени). Этот протокол определен в RFC 3550 вместе с RTP. Он занимается поддержкой обратной связи, синхронизацией, обеспечением пользовательского интерфейса, однако не занимается передачей каких-либо медиаданных.

Первая его функция может использоваться для обратной связи по задержкам, колебаниям времени задержки или джиттеру, пропускной способности, перегрузке и другим свойствам сети, о которых сообщается источникам. Полученная информация может приниматься во внимание кодировщиком для увеличения скорости передачи данных (что приведет к улучшению качества), когда это позволяет делать состояние сети, или уменьшения скорости при возникновении в сети каких-либо проблем. Постоянная обратная связь обеспечивает динамическую настройку алгоритмов кодирования на обеспечение наилучшего качества при текущих обстоятельствах. Например, пропускная способность при передаче потока может как увеличиваться, так и уменьшаться, и в соответствии с этим могут изменяться методы кодирования — скажем, MP3 может заменяться 8-битным PCM или дельта-кодированием. Поле Тип данных сообщает приемнику о том, какой алгоритм кодирования применяется для данного пакета, что позволяет изменять их по требованию при передаче потока.

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

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

Наконец, RTCP позволяет именовать различные источники (например, с помощью обычного ASCII-текста). Эта информация может отображаться на приемнике, позволяя определить источник текущего потока.

Более подробную информацию о протоколе RTP можно найти в (Perkins, 2002).

Буферизация и контроль джиттера при воспроизведении

Когда информация попадает на приемник, необходимо в правильный момент времени начать ее воспроизведение. В общем случае этот момент времени не совпадает со временем прибытия RTP-пакета, поскольку время прохождения через сеть для разных пакетов немного отличается. Даже если отправитель будет передавать их в сеть через одинаковые промежутки времени, они все равно будут приходить к получателю с разным интервалом. Такое варьирование времени задержки называется джиттером (jitter). Если медиаданные будут проигрываться сразу же по прибытии, даже небольшой джиттер может вызвать серьезные помехи: изображение может быть прерывистым, а звук — неразборчивым.

Решение этой проблемы состоит в буферизации пакетов на приемнике перед их воспроизведением. В примере, изображенном на рис. 6.28, мы видим поток пакетов, прибывающих на место назначения с достаточно большим джиттером. Пакет 1 был передан с сервера в момент времени t = 0 с и прибыл к клиенту в момент времени t = 1 с. Пакет 2 задерживается и прибывает через 2 с. По прибытии пакеты помещаются в буфер на машине клиента.

В момент времени t = 10 с начинается воспроизведение. В буфере уже находятся пакеты с 1 по 6, поэтому их можно доставать оттуда через равные промежутки времени и тем самым обеспечить равномерное воспроизведение. В общем случае равные промежутки времени использовать не обязательно, так как метки времени RTP содержат информацию о том, когда следует начать воспроизведение.

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

Рис. 6.28. Выравнивание выходного потока с помощью буферизации пакетов

При равномерном воспроизведении ключевую роль играет задержка воспроизведения (playback point), то есть время, которое получатель должен ждать медиаданных, прежде чем начать их воспроизведение. Этот параметр зависит от джиттера. Различие между соединением с маленьким и большим джиттером показано на рис. 6.29. Средняя задержка может отличаться не сильно, однако при большом джиттере может потребоваться задержка воспроизведения, захватывающая 99 % пакетов — гораздо больше, чем при маленьком джиттере.

Чтобы правильно подобрать задержку воспроизведения, приложение может измерять джиттер, вычисляя разницу между значениями меток времени RTP и временем прибытия. Эта разница (плюс некоторая константа) и составляет задержку каждого отдельного пакета. Однако некоторые факторы, такие как конкурирующий трафик и изменение маршрутов, могут стать причиной изменения времени задержки. Приложения должны учитывать это и при необходимости менять задержку воспроизведения. Но при неправильной реализации такое изменение может вызвать сильные помехи. Одно из возможных решений для аудио состоит в том, чтобы корректировать задержку воспроизведения между сегментами речи (talkspurts), то есть во время пауз. Разница между короткой паузой и чуть более длинной вряд ли будет заметна. Чтобы это было возможным, RTP позволяет приложениям отмечать начало нового сегмента речи с помощью маркера M.

Рис. 6.29. Джиттер: а — большой; б — маленький

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

6.5. Транспортные протоколы Интернета: TCP

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

6.5.1. Основы TCP

Протокол TCP (Transmission Control Protocol протокол управления передачей)

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

Протокол TCP был описан в RFC 793 в сентябре 1981 года. Со временем он был во многом усовершенствован, были исправлены различные ошибки и неточности. На сегодняшний день существует множество других RFC, являющихся дополнениями к RFC 793 (что позволяет судить о степени распространения этого протокола): уточнения и исправления описаны в RFC 1122, расширения для высокой производительности — в RFC 1323, выборочные подтверждения — в RFC 2018, контроль перегрузки — в RFC 2581, использование полей заголовка для качества обслуживания — в RFC 2873, усовершенствованные таймеры повторной передачи — в RFC 2988, явные уведомления о перегрузке — в RFC 3168. Поскольку это далеко не полный список, для удобной работы со всеми этими RFC был создан специальный указатель (конечно же, в виде еще одного RFC-документа) — RFC 4614.

Каждая машина, поддерживающая протокол TCP, обладает транспортной подсистемой TCP, являющейся либо библиотечной процедурой, либо пользовательским процессом, либо (чаще всего) частью ядра системы. В любом случае, транспортная подсистема управляет TCP-потоками и интерфейсом с IP-уровнем. TCP-подсистема принимает от локальных процессов пользовательские потоки данных, разбивает их на куски, не превосходящие 64 Кбайт (на практике это число обычно равно 1460 байтам данных, что позволяет поместить их в один кадр Ethernet с заголовками IP и TCP), и посылает их в виде отдельных IP-дейтаграмм. Когда IP-дейтаграммы с TCP-данными прибывают на машину, они передаются TCP-подсистеме, которая восстанавливает исходный байтовый поток. Для простоты мы иногда будем употреблять «TCP» для обозначения транспортной подсистемы TCP (части программного обеспечения) или протокола TCP (набора правил). Из контекста будет понятно, что имеется в виду. Например, в выражении «Пользователь передает данные TCP» подразумевается, естественно, транспортная подсистема TCP.

Уровень IP не гарантирует правильной доставки дейтаграмм и не накладывает ограничений на скорость их отправки. Именно TCP приходится выбирать правильную скорость отправки (следуя целям эффективного использования пропускной способности и предотвращения перегрузок), следить за истекшими интервалами ожидания и в случае необходимости заниматься повторной передачей дейтаграмм, не дошедших до места назначения. Бывает, что дейтаграммы прибывают в неправильном порядке. Восстанавливать сообщения из таких дейтаграмм обязан также TCP. Таким образом, протокол TCP призван обеспечить хорошую производительность и надежность, о которой мечтают многие приложения и которая не предоставляется протоколом IP.

6.5.2. Модель сервиса TCP

В основе сервиса TCP лежат так называемые сокеты (гнезда или конечные точки), создаваемые как отправителем, так и получателем. Они обсуждались в разделе 6.1.3. У каждого сокета есть номер (адрес), состоящий из IP-адреса хоста и 16-битного номера, локального по отношению к хосту, называемого портом. Портом в TCP называют TSAP-адрес. Для обращения к сервису TCP между сокетом одной машины и сокетом другой машины должно быть явно установлено соединение. Базовые операции сокетов приведены в табл. 6.2.

Один сокет может использоваться одновременно для нескольких соединений. Другими словами, два и более соединения могут оканчиваться одним сокетом. Соединения различаются по идентификаторам сокетов на обоих концах — (socketl, socket2). Номера виртуальных каналов или другие идентификаторы не используются.

Номера портов со значениями ниже 1024 зарезервированы стандартными сервисами и доступны только привилегированным пользователям (например, root в UNIX-системах). Они называются известными портами (well-known ports). Например, любой процесс, желающий удаленно загрузить почту с хоста, может связаться с портом 143 хоста-адресата и обратиться, таким образом, к его IMAP-демону. Список известных портов приведен на сайте www.iana.org. Таких портов на данный момент более 700. Некоторые из них включены в табл. 6.4.

Порты с номерами от 1024 до 49151 можно зарегистрировать через IANA для непривилегированных пользователей, однако приложения могут выбирать свои собственные порты (что они, как правило, и делают). К примеру, приложение BittTorrent для однорангового совместного доступа к файлам (неофициально) использует порты 6881-6887, однако другие порты также возможны.

Можно было бы, конечно, связать FTP-демона с портом 21 еще во время загрузки, тогда же связать демона SSH с портом 22 и т. д. Однако, если бы мы так сделали, мы бы только зря заняли память информацией о демонах, которые, на самом деле, большую часть времени простаивают. Вместо этого обычно пользуются услугами одного демона, называемого в UNIX inetd (Internet daemon), который связывается с несколькими портами и ожидает первое входящее соединение. Когда оно происходит, inetd создает новый процесс, для которого вызывается подходящий демон, обрабатывающий запрос. Таким образом, постоянно активен только inetd, остальные вызываются только тогда, когда для них есть работа. Inetd имеет специальный конфигурационный файл, из которого он может узнать о назначении портов. Это значит, что системный администратор может настроить систему таким образом, чтобы с самыми загруженными портами (например, 80) были связаны постоянные демоны, а с остальными — inetd.

Таблица 6.4. Некоторые зарезервированные порты

Порт

Протокол

Использование

20, 21

FTP

Передача файлов

22

SSH

Дистанционный вход в систему, замена Telnet

25

SMTP

Электронная почта

80

HTTP

Всемирная паутина (World Wide Web)

110

POP-3

Удаленный доступ к электронной почте

143

IMAP

Удаленный доступ к электронной почте

443

HTTPS

Защита от угроз (HTPP через SSL/TLS)

543

RTSP

Контроль воспроизведения мультимедиа

631

IPP

Коллективное использование принтера

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

TCP-соединение представляет собой байтовый поток, а не поток сообщений. Границы между сообщениями не сохраняются. Например, если отправляющий процесс записывает в TCP-поток четыре 512-байтовых порции данных, эти данные могут быть доставлены получающему процессу в виде четырех 512-байтовых порций, двух 1024-байтовых порций, одной 2048-байтовой порции (рис. 6.30) или как-нибудь еще. Нет способа, которым получатель смог бы определить, каким образом записывались данные.

Рис. 6.30. Четыре 512-байтовых сегмента, посланные как отдельные IP-дейтаграммы (а);

2048 байт данных, доставленные приложению с помощью одного вызова процедуры READ (б)

Файлы в системе UNIX также обладают этим свойством. Программа, читающая файл, не может определить, как был записан этот файл: поблочно, побайтно или сразу целиком. Как и в случае с файлами системы UNIX, TCP-программы не имеют представления о назначении байтов и не интересуются этим. Байт для них — просто байт.

Получив данные от приложения, протокол TCP может послать их сразу или поместить в буфер, чтобы послать большую порцию данных, по своему усмотрению. Однако иногда приложению бывает необходимо, чтобы данные были посланы немедленно. Допустим, например, что пользователь интерактивной игры хочет отправить поток обновлений. Важно, чтобы обновления передавались сразу же, а не сохранялись в буфере до появления других обновлений. Чтобы можно было вынудить передачу данных, в TCP существует флаг PUSH (протолкнуть). Изначально предполагалось, что с помощью этого флага приложения будут сообщать TCP о том, что не нужно задерживать передачу пакета. Однако приложения не могут устанавливать такие флаги при отправке данных. Вместо этого в различных операционных системах существуют специальные параметры, позволяющие ускорить передачу данных (например, TCP_NONDELAY в Windows и Linux).

Для тех, кто интересуется доисторическими методами Интернета, мы расскажем об интересной особенности службы TCP, которая все еще входит в состав протокола, но используется редко. Речь пойдет о срочных данных (urgent data). Когда часть данных обладает высоким приоритетом, то есть должна обрабатываться сразу же, — например, если пользователь, взаимодействующий с программой в интерактивном режиме, нажимает Ctrl-C, чтобы прервать начавшийся удаленный процесс, — посылающее приложение может поместить в выходной поток данных управляющую информацию и передать ее TCP-службе вместе с флагом URGENT (срочно). Этот флаг заставляет TCP-подсистему прекратить накопление данных и без промедления передать в сеть все, что у нее есть для данного соединения.

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

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

6.5.3. Протокол TCP

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

Ключевым свойством TCP, определяющим всю структуру протокола, является то, что в TCP-соединении у каждого байта есть свой 32-разрядный порядковый номер. В первые годы существования Интернета базовая скорость передачи данных между маршрутизаторами по выделенным линиям составляла 56 Кбит/с. Хосту, постоянно выдающему данные с максимальной скоростью, потребовалось бы больше недели на то, чтобы порядковые номера совершили полный круг. При нынешних скоростях порядковые номера могут кончиться очень быстро, об этом еще будет сказано ниже. Отдельные 32-разрядные порядковые номера используются для указания позиции скользящего окна в одном направлении и подтверждений в обратном направлении, о чем также будет сказано ниже.

Отправляющая и принимающая TCP-подсистемы обмениваются данными в виде сегментов. Сегмент TCP состоит из фиксированного 20-байтового заголовка (плюс необязательная часть), за которым могут следовать байты данных. Размер сегментов определяется программным обеспечением TCP. Оно может объединять в один сегмент данные, полученные в результате нескольких операций записи, или, наоборот, распределять результат одной записи между несколькими сегментами. Размер сегментов ограничен двумя пределами. Во-первых, каждый сегмент, включая TCP-заголовок, должен помещаться в 65 515-байтное поле полезной нагрузки IP-пакета. Во-вторых, в каждом канале есть максимальный размер передаваемого блока (MTU, Maximum Transfer Unit). На отправителе и получателе каждый сегмент должен помещаться в MTU, чтобы он мог передаваться и приниматься в отдельном пакете, не разделенном на фрагменты. На практике максимальный размер передаваемого блока составляет обычно 1500 байт (что соответствует размеру поля полезной нагрузки Ethernet), и таким образом определяется верхний предел размера сегмента.

Тем не менее, если IP-пакет, содержащий TCP-сегменты, проходит по пути со слишком низким MTU, его фрагментация возможна. Но в таком случае снижается производительность, а также возникают другие проблемы (Kent и Mogul, 1987). Вместо этого реализации TCP выполняют обнаружение MTU маршрута. При этом используется метод, описанный в RFC 1191, — о нем мы говорили в разделе 5.5.5. Этот метод вычисляет минимальное значение MTU по всем каналам пути, используя сообщения об ошибках ICMP. На основе этого значения TCP выбирает размер сегмента, позволяющий избежать фрагментации.

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

Хотя этот протокол кажется простым, в нем имеется несколько деталей, которые следует рассмотреть подробнее. Сегменты могут приходить в неверном порядке. Так, например, возможна ситуация, в которой байты с 3072 по 4095 уже прибыли, но подтверждение для них не может быть выслано, так как байты с 2048 по 3071 еще не получены. К тому же сегменты могут задерживаться в сети так долго, что у отправителя истечет время ожидания, и он передаст их снова. Переданный повторно сегмент может включать в себя уже другие диапазоны фрагментов, поэтому потребуется очень аккуратное администрирование для определения номеров байтов, которые уже были приняты корректно. Тем не менее, поскольку каждый байт в потоке единственным образом определяется по своему сдвигу, эта задача оказывается реальной.

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

6.5.4. Заголовок TCP-сегмента

На рис. 6.31 показана структура заголовка TCP-сегмента. Каждый сегмент начинается с 20-байтного заголовка фиксированного формата. За ним могут следовать дополнительные поля (параметры). После дополнительных полей может располагаться до 65 535 - 20 - 20 = 65 495 байт данных, где первые 20 байт — это IP-заголовок, а вторые — TCP-заголовок. Сегменты могут и не содержать данных. Такие сегменты часто применяются для передачи подтверждений и управляющих сообщений.

Рассмотрим TCP-заголовок поле за полем. Поля Порт получателя и Порт отправителя являются идентификаторами локальных конечных точек соединения. TCP-порт вместе с IP-адресом хоста образуют уникальный 48-битный идентификатор конечной точки. Пара таких идентификаторов, относящихся к источнику и приемнику, однозначно определяет соединение. Этот идентификатор соединения называется кортежем из пяти компонентов (5 tuple), так как он включает пять информационных составляющих: протокол (TCP), IP-адрес источника, порт источника, IP-адрес получателя и порт получателя.

Поля Порядковый номер и Номер подтверждения выполняют свою обычную функцию. Обратите внимание: поле Номер подтверждения относится к следующему по порядку ожидаемому байту, а не к последнему полученному. Это накопительное подтверждение (cumulative acknowledgement), так как один номер объединяет в себе информацию обо всех полученных данных. Сфера его применения не выходит за рамки потерянных данных. Оба поля 32-разрядные, так как в TCP-потоке нумеруется каждый байт данных.

Рис. 6.31. Заголовок TCP

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

Следом идет неиспользуемое 4-битное поле. Тот факт, что эти биты не используются уже в течение 30 лет (а востребованными оказываются только 2 бита изначально 6-битного поля), является свидетельством того, насколько хорошо продуман дизайн TCP. Иначе протоколы использовали бы эти биты, чтобы справиться с недостатками TCP.

Затем следуют восемь 1-битовых флагов. CWR и ECE сообщают о перегрузках сети в случае, если используется явное уведомление о насыщении (см. RFC 3168). Когда TCP-приемник узнает, что сеть перегружена, он с помощью флага ECE передает TCP-отправителю сигнал ECN-эхо, предлагая ему уменьшить скорость отправки. После того как TCP-приемник уменьшил скорость отправки, он сообщает об этом TCP-приемнику с помощью флага CWR с сигналом Окно насыщения уменьшено, после чего приемник перестает передавать сигнал ECN-эхо. Подробнее о роли явных уведомлений о перегрузке в контроле перегрузки TCP мы поговорим в разделе 6.5.10.

Бит URG устанавливается в 1 в случае использования поля Указатель на срочные данные, содержащего смещение в байтах от текущего порядкового номера байта до места расположения срочных данных. Таким образом, в протоколе TCP реализуются прерывающие сообщения. Как уже упоминалось, этот метод позволяет отправителю передать получателю сигнал, не вовлекая в это TCP; он используется редко.

Если бит ACKустановлен в 1, значит, поле Номер подтверждениясодержит осмысленные данные. Для большинства пакетов это так. В противном случае данный сегмент не содержит подтверждения, и поле Номер подтвержденияпросто игнорируется.

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

Бит RSTиспользуется для внезапного сброса состояния соединения, которое из-за сбоя хоста или по другой причине попало в тупиковую ситуацию. Кроме того, он используется для отказа от неверного сегмента или от попытки создать соединение. Если вы получили сегмент с установленным битом RST, это означает наличие какой-то проблемы.

Бит SYNприменяется для установки соединения. У запроса соединения бит SYN= 1, а бит ACK= 0, это означает, что поле подтверждения не используется. Но в ответе на этот запрос содержится подтверждение, поэтому значения этих битов в нем равны: SYN= 1, ACK= 1. Таким образом, бит SYNиспользуется для обозначения как сегментов CONNECTION REQUEST, так и CONNECTION ACCEPTED, а бит ACK— чтобы отличать их друг от друга.

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

Управление потоком в протоколе TCP осуществляется при помощи скользящего окна переменного размера. Поле Размер окнасообщает, сколько байт может быть послано после байта, получившего подтверждение. Значение поля Размер окнаможет быть равно нулю, это означает, что все байты вплоть до Номер подтверждения-1 получены, но получатель еще не обработал эти данные, и поэтому остальные байты он пока принять не может. Разрешение на дальнейшую передачу может быть получено путем отправки сегмента с таким же значением поля Номер подтвержденияи ненулевым значением поля Размер окна.

В главе 3 мы обсуждали протоколы, в которых подтверждения приема кадров были связаны с разрешениями на продолжение передачи. Эта связь была следствием жестко закрепленного размера скользящего окна в этих протоколах. В ТСР подтверждения отделены от разрешений на передачу данных. В сущности, приемник может сказать: «Я получил байты вплоть до k-го, но я сейчас не хочу продолжать прием данных». Такое разделение (выражающееся в скользящем окне переменного размера) придает протоколу дополнительную гибкость. Ниже мы обсудим этот аспект более детально.

Поле Контрольная суммаслужит для повышения надежности. Как и в случае UDP, оно содержит контрольную сумму заголовка, данных и псевдозаголовка. Но в отличие от UDP псевдозаголовок этого поля содержит номер протокола TCP (6), а контрольная сумма является обязательной. Для более подробной информации см. раздел 6.4.1.

Поле Параметрыпредоставляет дополнительные возможности, не покрываемые стандартным заголовком. Существует множество параметров и некоторые из них широко используются. Они имеют разную длину, кратную 32 битам (лишнее место заполняется нулями), и могут доходить до отметки в 40 байт — максимального размера заголовка TCP. При установлении соединения факультативные поля могут использоваться для того, чтобы договориться с противоположной стороной или просто сообщить ей о характеристиках этого соединения. Существуют поля, сохраняющиеся в течение всего времени жизни соединения. Все факультативные поля имеют формат Тип-Длина-Значение.

С помощью одного из таких полей каждый хост может указать максимальный размер сегмента (MSS, Maximum Segment Size), который он может принять. Чем больше размер используемых сегментов, тем выше эффективность, так как при этом снижается удельный вес накладных расходов в виде 20-байтных заголовков, однако не все хосты способны принимать очень большие сегменты. Хосты могут сообщить друг другу максимальный размер сегмента во время установки соединения. По умолчанию этот размер равен 536 байтам. Все хосты обязаны принимать TCP-сегменты размером 536 + 20 = 556 байт. Для каждого из направлений может быть установлен свой максимальный размер сегмента.

Для линий с большой скоростью передачи и/или большой задержкой окно размером в 64 Кбайт, соответствующее 16-битному полю, оказывается слишком маленьким. Так, для линии OC-12 (приблизительно 600 Мбит/с) полное окно может быть передано в линию менее чем за 1 мс. Если значение времени распространения сигнала в оба конца составляет 50 мс (что типично для трансконтинентального оптического кабеля), 98 % времени отправитель будет заниматься ожиданием подтверждения. Больший размер окна мог бы улучшить эффективность. Параметр масштаб окна позволяет двум хостам договориться о масштабе окна при установке соединения. Это число позволяет обеим сторонам сдвигать поле Размер окна до 14 разрядов влево, обеспечивая расширение размера окна до 230 байт (1 Гбайт). Большинство реализаций протокола TCP поддерживают эту возможность.

Для меток времени, передаваемых от отправителя к получателю и обратно, существует одноименный параметр. Если во время настройки соединения этот параметр решено было использовать, он добавляется в каждый пакет. Он позволяет получить данные о круговой задержке, которые, в свою очередь, используются для определения потери пакетов. Также он используется в качестве логического расширения 32-битного порядкового номера. При быстром соединении порядковые номера могут проходить полный круг очень быстро, и в результате новые и старые данные будет невозможно отличить. Детектирование повторного использования порядковых номеров (PAWSProtection Against Wrapped Sequence numbers) удаляет сегменты со старыми метками времени, позволяя избежать этой проблемы. Наконец, с помощью выборочного подтверждения (SACK, Selective ACKnowledgement) получатель может сообщать отправителю диапазоны порядковых номеров доставленных пакетов. Этот параметр является дополнением к Номеру подтверждения и используется в случаях, когда после потери пакета данные все равно были доставлены (возможно, в виде копии). Новые данные не отражены в поле заголовка Номер подтверждения, так как оно содержит только следующий по порядку ожидаемый байт. Если использовать выборочное подтверждение, отправитель всегда будет знать, какие данные есть у получателя, и сможет выполнять повторную передачу только тогда, когда это действительно нужно. Выборочное подтверждение описано в RFC 2108 и RFC 2883. В последнее время эта схема используется все чаще. О ее применении при контроле перегрузки мы поговорим в разделе 6.5.10.

6.5.5. Установка TCP-соединения

В протоколе TCP соединения устанавливаются с помощью «тройного рукопожатия». Чтобы установить соединение, одна сторона (например, сервер) пассивно ожидает входящего соединения, выполняя базовые операции LISTEN и ACCEPT, либо указывая конкретный источник, либо не указывая его.

Другая сторона (например, клиент) выполняет операцию CONNECT, указывая IP-адрес и порт, с которым она хочет установить соединение, максимальный размер TCP-сегмента и, по желанию, некоторые данные пользователя (например, пароль). Примитив CONNECT посылает TCP-сегмент с установленным битом SYN и сброшенным битом ACK и ждет ответа.

Когда этот сегмент прибывает в пункт назначения, TCP-подсистема проверяет, выполнил ли какой-нибудь процесс операцию LISTEN, указав в качестве параметра тот же порт, который содержится в поле Порт получателя. Если такого процесса нет, она отвечает отправкой сегмента с установленным битом RST для отказа от соединения.

Рис. 6.32. Установка TCP-соединения в нормальном случае (а); одновременная установка соединения обеими сторонами (б)

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

Если два хоста одновременно попытаются установить соединение друг с другом, то последовательность происходящих при этом событий будет соответствовать рис. 6.32, б. В результате будет установлено только одно соединение, а не два, так как пара конечных точек однозначно определяет соединение. То есть если оба соединения пытаются идентифицировать себя с помощью пары (x, y), делается всего одна табличная запись для (x, y).

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

Однако проблема реализации схемы «тройного рукопожатия» состоит в том, что слушающий процесс должен помнить свой порядковый номер до тех пор, пока он не отправит свой собственный ,5ТА-сегмент. Это значит, что злонамеренный отправитель может блокировать ресурсы хоста, отправляя на него поток ,5ТА-сегментов и не разрывая соединение. Такие атаки называются затоплением SYN-сегментами (SYN flood). В 1990-е годы из-за них многие веб-серверы оказались парализованными.

Один из методов, позволяющих обезопасить себя от таких атак, называется SYN cookies. Вместо того чтобы запоминать порядковый номер, хост генерирует криптографическое значение номера, записывает его в исходящий сегмент и забывает. Если «тройное рукопожатие» завершается, этот порядковый номер (увеличенный на 1) вернется на хост. Хост может повторно сгенерировать правильный порядковый номер, вычислив значение той же криптографической функции, при условии, что известны входные данные (это может быть IP-адрес и порт другого хоста, а также какое-то секретное значение). С помощью этой процедуры хост может проверять правильность подтвержденного порядкового номера без необходимости отдельно запоминать этот номер. Одна из тонкостей этого метода состоит в том, что он не работает с дополнительными полями (параметрами) TCP. Поэтому SYN cookies можно использовать только в случае затопления SYN-сегментами. Но в целом это очень интересный прием. Более подробно см. RFC 4987 и (Lemon, 2002).

6.5.6. Разрыв соединения TCP

Хотя TCP-соединения являются полнодуплексными, чтобы понять, как происходит их разъединение, лучше считать их парами симплексных соединений. Каждое симплексное соединение разрывается независимо от своего напарника. Чтобы разорвать соединение, любая из сторон может послать TCP-сегмент с установленным в единицу битом НА, это означает, что у него больше нет данных для передачи. Когда этот TCP-сегмент получает подтверждение, это направление передачи закрывается. Тем не менее данные могут продолжать передаваться неопределенно долго в противоположном направлении. Соединение разрывается, когда оба направления закрываются. Обычно для разрыва соединения требуются четыре TCP-сегмента: по одному с битом FIA и по одному с битом ACK в каждом направлении. Первый бит ACK и второй бит НА могут также содержаться в одном TCP-сегменте, что уменьшит количество сегментов до трех.

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

Чтобы избежать проблемы двух армий (см. раздел 6.2.3), используются таймеры. Если ответ на посланный FIN-сегмент не приходит в течение двух максимальных интервалов времени жизни пакета, отправитель FIN-сегмента разрывает соединение. Другая сторона, в конце концов, заметит, что ей никто не отвечает, и также разорвет соединение. Хотя такое решение и не идеально, но, учитывая недостижимость идеала, приходится пользоваться тем, что есть. На практике проблемы возникают довольно редко.

6.5.7. Модель управления TCP-соединением

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

Таблица 6.5. Состояния конечного автомата, управляющего TCP-соединением

Состояние

CLOSED

LISTEN SYN RCVD SYN SENT ESTABLISHED FIN WAIT 1 FIN WAIT 2 TIME WAIT CLOSING CLOSE WAIT LAST ACK

Описание

Закрыто. Соединение не является активным и не находится в процессе установления

Ожидание. Сервер ожидает входящего запроса

Прибыл запрос соединения. Ожидание подтверждения

Запрос соединения послан. Приложение начало открывать соединение

Установлено. Нормальное состояние передачи данных

Приложение сообщило, что ему больше нечего передавать

Другая сторона согласна разорвать соединение

Ожидание, пока в сети не исчезнут все пакеты

Обе стороны попытались одновременно закрыть соединение

Другая сторона инициировала разъединение

Ожидание, пока в сети не исчезнут все пакеты

Каждое соединение начинается в состоянии CLOSED (закрытое). Оно может покинуть это состояние, предпринимая либо активную (CONNECT), либо пассивную (LISTEN) попытку открыть соединение. Если противоположная сторона осуществляет противоположные действия, соединение устанавливается и переходит в состояние ESTABLISHED. Инициатором разрыва соединения может выступить любая сторона. По завершении процесса разъединения соединение возвращается в состояние CLOSED.

Конечный автомат показан на рис. 6.33. Типичный случай клиента, активно соединяющегося с пассивным сервером, показан жирными линиями — сплошными для клиента и пунктирными для сервера. Тонкие линии обозначают необычные последовательности событий. Каждая линия на рис. 6.33 маркирована парой событие/дей-ствие. Событие может представлять собой либо обращение пользователя к системной процедуре (CONNECT, LISTEN, SEND или CLOSE), либо прибытие сегмента (SYN, FIN, ACKили RST), либо, в одном случае, окончание периода ожидания, равного двойному времени жизни пакетов. Действие может состоять в отправке управляющего сегмента (SYN, FIN или RST). Впрочем, может не предприниматься никакого действия, что обозначается прочерком. В скобках приводятся комментарии.

Рис. 6.33. Конечный автомат TCP-соединения. Жирная сплошная линия показывает нормальный путь клиента. Жирным пунктиром показан нормальный путь сервера. Тонкими линиями обозначены необычные события

Диаграмму легче всего понять, если сначала проследовать по пути клиента (сплошная жирная линия), а затем — по пути сервера (жирный пунктир). Когда приложение на машине клиента вызывает операцию CONNECT, локальная TCP-подсистема создает запись соединения, помечает его состояние как SYN SENT и посылает SYN-сегмент. Примечательно, что несколько приложений одновременно могут открыть несколько соединений, поэтому свое состояние, хранящееся в записи соединения, имеется у каждого отдельного соединения. Когда прибывает сегмент SYN + ACK, TCP-подсистема посылает последний ACK-сегмент «тройного рукопожатия» и переключается в состояние ESTABLISHED. В этом состоянии можно пересылать и получать данные.

Когда у приложения заканчиваются данные для передачи, оно выполняет операцию CLOSE, заставляющую локальную TCP-подсистему послать FIN-сегмент и ждать ответного ACK-сегмента (пунктирный прямоугольник с пометкой «активное разъединение»). Когда прибывает подтверждение, происходит переход в состояние FIN WAIT2, и одно направление соединения закрывается. Когда приходит встречный FIN-сегмент, в ответ на него также высылается подтверждение, и второе направление соединения также закрывается. Теперь обе стороны соединения закрыты, но TCP-подсистема выжидает в течение времени, равного удвоенному максимальному времени жизни пакета, чтобы можно было гарантировать, что все пакеты этого соединения больше не перемещаются по сети даже в том случае, если подтверждение было потеряно. Когда этот период ожидания истекает, TCP-подсистема удаляет запись о соединении.

Рассмотрим теперь управление соединением с точки зрения сервера. Сервер выполняет операцию LISTEN и переходит в режим ожидания запросов соединения. Когда приходит SYN-сегмент, в ответ на него высылается подтверждение, после чего сервер переходит в состояние SYN RCVD (запрос соединения получен). Когда в ответ на SYN-подтверждение сервера от клиента приходит ACK-сегмент, процедура «тройного рукопожатия» завершается, и сервер переходит в состояние ESTABLISHED. Теперь можно пересылать данные.

По окончании передачи данных клиент выполняет операцию CLOSE, в результате чего на сервер прибывает FIN-сегмент (пунктирный прямоугольник, обозначенный как пассивное разъединение). Теперь сервер выполняет операцию CLOSE, а FIN-сегмент посылается клиенту. Когда от клиента прибывает подтверждение, сервер разрывает соединение и удаляет запись о нем.

6.5.8. Скользящее окно TCP

Как уже было сказано выше, управление окном в TCP решает проблемы подтверждения корректной доставки сегментов и выделения буферов на приемнике. Например, предположим, что у получателя есть 4096-байтовый буфер, как показано на рис. 6.34. Если отправитель передает 2048-байтовый сегмент, который успешно принимается получателем, то получатель подтверждает его получение. Однако при этом у получателя остается всего лишь 2048 байт свободного буферного пространства (пока приложение не заберет сколько-нибудь данных из буфера), о чем он и сообщает отправителю, указывая соответствующий размер окна (2048) и номер следующего ожидаемого байта.

Необходимо исправить все обозначения «1К» на «1 Кбайт», «2К» на «2 Кбайт», «4К» на «4 Кбайт», а «3К» на «2 Кбайт» (для соответствия оригиналу).

Рис. 6.34. Управление окном в TCP

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

При нулевом размере окна отправитель не может посылать сегменты, за исключением двух случаев. Во-первых, разрешается посылать срочные данные, например, чтобы пользователь мог уничтожить процесс, выполняющийся на удаленной машине. Во-вторых, отправитель может послать 1-байтовый сегмент, прося получателя повторить информацию о размере окна и ожидаемом следующем байте. Такой пакет называется пробным сегментом (window probe). Стандарт TCP явно предусматривает эту возможность для предотвращения тупиковых ситуаций в случае потери объявления о размере окна.

Отправители не обязаны передавать данные сразу как только они приходят от приложения. Также никто не требует от получателей посылать подтверждения как можно скорее. Например, на рис. 6.34 TCP-подсистема, получив от приложения первые 2 Кбайт данных и зная, что размер окна равен 4 Кбайт, была бы совершенно права, если бы просто сохранила полученные данные в буфере до тех пор, пока не прибудут

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

Рассмотрим соединение (к примеру, telnet или SSH) с удаленным терминалом, реагирующим на каждое нажатие клавиши. В худшем случае, когда символ прибывает к передающей TCP-подсистеме, она создает 21-байтовый TCP-сегмент и передает его IP-уровню, который, в свою очередь, посылает 41-байтовую IP-дейтаграмму. На принимающей стороне TCP-подсистема немедленно отвечает 40-байтовым подтверждением (20 байт TCP-заголовка и 20 байт IP-заголовка). Затем, когда удаленный терминал прочитает этот байт из буфера, TCP-подсистема пошлет обновленную информацию о размере буфера, передвинув окно на 1 байт вправо. Размер этого пакета также составляет 40 байт. Наконец, когда удаленный терминал обработает этот символ, он отправляет обратно эхо, передаваемое 41-байтовым пакетом. Итого для каждого введенного с клавиатуры символа пересылается четыре пакета общим размером 162 байта. В условиях дефицита пропускной способности линий этот метод работы нежелателен.

Для улучшения ситуации многие реализации TCP используют отложенные подтверждения (delayed acknowledgements). Идея этого метода состоит в том, чтобы задерживать подтверждения и обновления размера окна на время до 500 мс в надежде получить дополнительные данные, вместе с которыми можно будет отправить подтверждение одним пакетом. Если терминал успеет выдать эхо в течение 500 мс, удаленной стороне нужно будет выслать только один 41-байтовый пакет, таким образом, нагрузка на сеть снизится вдвое.

Хотя отложенные подтверждения и снижают нагрузку на сеть, тем не менее эффективность использования сети отправителем, передающим множество маленьких пакетов (к примеру, 41-байтовые пакеты с 1 байтом реальных данных), продолжает оставаться невысокой. Метод, позволяющий повысить эффективность, известен как алгоритм Нагля (Nagle’s algorithm) (Nagle, 1984). Предложение Нагля звучит довольно просто: если данные поступают отправителю маленькими порциями, отправитель просто передает первый фрагмент, а остальные помещает в буфер, пока не будет получено подтверждение приема первого фрагмента. После этого можно переслать все накопленные в буфере данные в виде одного TCP-сегмента и снова начать буферизацию до получения подтверждения о доставке следующего сегмента. Таким образом, в каждый момент времени может передаваться только один маленький пакет. Если за время прохождения пакета в оба конца приложение отправляет много порций данных, алгоритм Нагля объединяет несколько таких порций в один сегмент, и, таким образом, нагрузка на сеть существенно снижается. Кроме того, согласно этому алгоритму новый пакет должен быть отправлен, если объем данных в буфере превышает максимальный размер сегмента.

Алгоритм Нагля широко применяется различными реализациями протокола TCP, однако иногда бывают ситуации, в которых его лучше отключить. В частности, интерактивным играм через Интернет обычно требуется быстрый поток маленьких пакетов с обновлениями. Если буферизировать эти данные для пакетной пересылки, игра будет работать неправильно, и пользователи будут недовольны. Более тонкая проблема заключается в том, что иногда при задержке подтверждений использование алгоритма Нагля может приводить к временным тупиковым ситуациям: получатель ждет данных, к которым можно присоединить подтверждение, а отправитель ждет подтверждения, без которого не будут переданы новые данные. Из-за этого, в частности, может задерживаться загрузка веб-страниц. На случай таких проблем существует возможность отключения алгоритма Нагля (параметр TCP_NODELAY). Подробнее об этих и других решениях см. Mogul и Minshall (2001).

Еще одна проблема, способная значительно снизить производительность протокола TCP, известна под именем синдрома глупого окна (silly window syndrome) (Clark, 1982). Суть проблемы состоит в том, что данные пересылаются TCP-подсистемой крупными блоками, но принимающая сторона интерактивного приложения считывает их посимвольно. Чтобы ситуация стала понятнее, рассмотрим рис. 6.35. Начальное состояние таково: TCP-буфер приемной стороны полон (то есть размер его окна равен 0), и отправителю это известно. Затем интерактивное приложение читает один символ из TCP-потока. Принимающая TCP-подсистема радостно сообщает отправителю, что размер окна увеличился и что он теперь может послать 1 байт. Отправитель повинуется и посылает 1 байт. Буфер снова оказывается полон, о чем получатель и извещает, посылая подтверждение для 1-байтового сегмента с нулевым размером окна. И так может продолжаться вечно.

Рис. 6.35. Синдром глупого окна

Дэвид Кларк (David Clark) предложил запретить принимающей стороне отправлять информацию об однобайтовом размере окна. Вместо этого получатель должен подождать, пока в буфере не накопится значительное количество свободного места. В частности, получатель не должен отправлять сведения о новом размере окна до тех пор, пока он не сможет принять сегмент максимального размера, который он объявлял при установке соединения, или его буфер не освободился хотя бы наполовину. Кроме того, увеличению эффективности отправки может способствовать сам отправитель, отказываясь от отправки слишком маленьких сегментов. Вместо этого он должен подождать, пока размер окна не станет достаточно большим для того, чтобы можно было послать полный сегмент или, по меньшей мере, равный половине размера буфера получателя.

В задаче избавления от синдрома глупого окна алгоритм Нагля и решение Кларка дополняют друг друга. Нагль пытался решить проблему приложения, предоставляющего данные TCP-подсистеме посимвольно. Кларк старался разрешить проблему приложения, посимвольно получающего данные у TCP. Оба решения хороши и могут работать одновременно. Суть их состоит в том, чтобы не посылать и не просить передавать данные слишком малыми порциями.

Принимающая TCP-подсистема может пойти еще дальше в деле повышения производительности, просто обновляя информацию о размере окна большими порциями. Как и отправляющая TCP-подсистема, она также может буферизировать данные и блокировать запрос на чтение READ, поступающий от приложения, до тех пор, пока у нее не накопится большого объема данных. Таким образом, снижается количество обращений к TCP-подсистеме (и вместе с ними накладные расходы). Конечно, такой подход увеличивает время ожидания ответа, но для неинтерактивных приложений, например, при передаче файла, сокращение времени, затраченного на всю операцию, значительно важнее увеличения времени ожидания ответа на отдельные запросы.

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

Подтверждение может быть выслано, только если все данные вплоть до подтверждаемого байта получены. Это называется накопительным подтверждением. Если до получателя доходят сегменты 0, 1, 2, 4, 5, 6 и 7, он может подтвердить получение данных вплоть до последнего байта сегмента 2. Когда у отправителя истечет время ожидания, он передаст сегмент 3 еще раз. Если к моменту прибытия сегмента 3 получатель сохранит в буфере сегменты с 4 по 7, он сможет подтвердить получение всех байтов, вплоть до последнего байта сегмента 7.

6.5.9. Управление таймерами в TCP

В протоколе TCP используется много различных таймеров (по крайней мере, такова концепция). Наиболее важным из них является таймер повторной передачи (RTORetransmission TimeOut). Когда посылается сегмент, запускается таймер повторной передачи. Если подтверждение получения сегмента прибывает раньше, чем истекает период таймера, таймер останавливается. Если же, наоборот, период ожидания истечет раньше, чем прибудет подтверждение, сегмент передается еще раз (а таймер запускается снова). Соответственно возникает вопрос: каким должен быть интервал времени ожидания?

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

Рис. 6.36. Плотность вероятности времени прибытия подтверждения: а — на канальном уровне; б — для TCP

Протокол TCP вынужден работать в совершенно иных условиях. Функция распределения плотности вероятности для времени прибытия подтверждения на этом уровне выглядит значительно более полого (рис. 6.36, б ), а вариативность достаточно велика. Поэтому предсказать, сколько потребуется времени для прохождения данных от отправителя до получателя и обратно, весьма непросто. Если выбрать величину интервала ожидания слишком малой (например, Т1 на рис. 6.36, б), возникнут излишние повторные передачи, забивающие Интернет бесполезными пакетами. Если же установить значение этого интервала слишком большим (T2), то из-за увеличения времени ожидания в случае потери пакета пострадает производительность. Более того, среднее значение и величина дисперсии времени прибытия подтверждений может изменяться всего за несколько секунд при возникновении и устранении перегрузки.

Решение заключается в использовании динамического алгоритма, постоянно изменяющего величину периода ожидания, основываясь на измерениях производительности сети. Алгоритм, применяемый в TCP, разработан Джекобсоном (Jacobson) в 1988 году и работает следующим образом. Для каждого соединения в протоколе TCP предусмотрена переменная SRTT (Smoothed Round-Trip Time усредненная круговая задержка), в которой хранится текущее наилучшее ожидаемое время получения подтверждения для данного соединения. При передаче сегмента запускается таймер, который замеряет время, требуемое для получения подтверждения, а также запускает повторную передачу, если подтверждение не приходит в срок. Если подтверждение успевает вернуться, прежде чем истечет период ожидания, TCP-подсистема замеряет

время, потребовавшееся для его получения (R). Затем значение переменной SRTT обновляется по следующей формуле:

где а — весовой коэффициент, определяющий, насколько быстро забываются старые значения. Обычно он равен 7/8. Эта формула — взвешенное скользящее среднее (EWMA, Exponentially Weighed Moving Average) или фильтр низких частот, с помощью которого можно удалять шум.

Даже при известном значении переменной SRTT выбор периода ожидания подтверждения оказывается задачей нетривиальной. В первых реализациях TCP это значение вычислялось как 2xRTT, однако экспериментально было показано, что постоянный множитель является слишком негибким и плохо учитывает ситуации, при которых разброс значений времени прибытия подтверждения увеличивается. В частности, модели очередей случайного (то есть пуассоновского) трафика показывают, что когда нагрузка приближается к пропускной способности, задержка и ее разброс увеличиваются. В результате может сработать таймер повторной передачи, после чего будет отправлена копия пакета, хотя оригинальный пакет все еще будет в сети. Как правило, такие ситуации возникают именно при высокой нагрузке — и это не самое лучшее время для того, чтобы отправлять в сеть лишние пакеты.

Чтобы решить эту проблему, Джекобсон предложил сделать интервал времени ожидания чувствительным к отклонению круговой задержки и к усредненной круговой задержке. Для этого потребовалась еще одна сглаженная переменная RTTVAR (Round-Trip Time Variation, отклонение круговой задержки), которая вычисляется по формуле:

Как и в предыдущем случае, это взвешенное скользящее среднее. Как правило, в = 3/4. Значение интервала ожидания, RTO, устанавливается по формуле:

Выбор множителя 4 является произвольным, однако умножение целого числа на 4 может быть выполнено одной командой сдвига, а относительное количество излишних повторных передач при таком значении времени ожидания не превысит одного процента. Обратите внимание на то, что RTTVAR является не стандартным, а средним отклонением, но на практике их значения оказываются достаточно близкими. В работе Джекобсона приводится множество способов вычисления значений интервала ожидания с помощью только целочисленного сложения, вычитания и сдвига. Хотя для современных хостов такая экономия не представляет интереса, ее использования требует идея повсеместной применимости TCP: он должен работать как на суперкомпьютерах, так и на небольших устройствах. Для RFID-чипов его пока еще никто не реализовал, но вдруг? Кто знает, может быть.

Более подробные сведения о том, как вычислять это значение интервала ожидания, а также начальные значения переменных, можно найти в RFC 2988. Для таймера повторной передачи минимальное значение также устанавливается равным 1 с, независимо от предварительной оценки. Это значение нужно для того, чтобы избежать лишних повторных передач, основанных на измерениях (Allman и Paxson, 1999).

При получении данных для вычисления круговой задержки, R, возникает вопрос, что делать при повторной передаче сегмента. Когда наконец прибывает подтверждение для такого сегмента, непонятно, относится это подтверждение к первой передаче пакета или же к последней. Неверная догадка может серьезно снизить значение интервала ожидания. Эта проблема была обнаружена радиолюбителем Филом Карном (Phil Kam). Его интересовал вопрос передачи TCP/IP-пакетов с помощью коротковолновой любительской радиосвязи, известной своей ненадежностью. Предложение Ф. Карна было очень простым: не обновлять оценки для переданных повторно пакетов. Кроме того, при каждой повторной передаче время ожидания можно удваивать до тех пор, пока сегменты не пройдут с первой попытки. Это исправление получило название алгоритма Карна (Karn’s algorithm) (Kam и Partridge, 1987). Он применяется в большинстве реализаций протокола TCP.

В протоколе TCP используется не только таймер повторной передачи. Еще один применяемый в этом протоколе таймер называется таймером настойчивости (persistence timer). Он предназначен для предотвращения следующей тупиковой ситуации. Получатель посылает подтверждение, в котором указывает окно нулевого размера, давая тем самым отправителю команду подождать. Через некоторое время получатель посылает пакет с новым размером окна, но этот пакет теряется. Теперь обе стороны ожидают действий противоположной стороны. Когда срабатывает таймер настойчивости, отправитель посылает получателю пакет с вопросом, не изменилось ли текущее состояние. В ответ получатель сообщает текущий размер окна. Если он все еще равен нулю, таймер настойчивости запускается снова, и весь цикл повторяется. Если же окно увеличилось, отправитель может передавать данные.

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

Последний таймер, используемый в каждом TCP-соединении, — это таймер, запускаемый в состоянии TIME WAIT конечного автомата при закрытии соединения. Он отсчитывает двойное время жизни пакета, чтобы гарантировать, что после закрытия соединения в сети не останутся созданные им пакеты.

6.5.10. Контроль перегрузки в TCP

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

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

Общие вопросы, касающиеся контроля перегрузки, мы уже обсуждали в разделе 6.3. Основная мысль заключалась в следующем: транспортный протокол, использующий закон управления AIMD (Additive Increase Multiplicative Decrease, аддитивное увеличение мультипликативное уменьшение) при получении двоичных сигналов сети о перегрузке, сходится к справедливому и эффективному распределению пропускной способности. Контроль перегрузки в TCP реализует этот подход с помощью окна, а в качестве сигнала используется потеря пакетов. В каждый момент времени в сети может находиться не более чем фиксированное число байт от каждого отправителя. Это число байт составляет размер окна перегрузки. Соответственно, скорость отправки равна размеру окна, деленному на круговую задержку соединения. Размер окна задается в соответствии с правилом AIMD.

Как вы наверняка помните, помимо окна перегрузки существует также окно управления потоком, определяющее число байт, которое получатель может поместить в буфер. Оба эти параметра играют важную роль: число байт, которое отправитель может передать в сеть, равно размеру меньшего из этих окон. Таким образом, эффективное окно — меньшее из того, что устраивает отправителя, и того, что устраивает получателя. Здесь необходимо участие обеих сторон. TCP остановит отправку данных, если одно из окон временно окажется заполненным. Если получатель говорит: «Посылайте 64 Кбайт», но отправитель знает, что если он пошлет более 32 Кбайт, то в сети образуется затор, он посылает все же 32 Кбайт. Если же отправитель знает, что сеть способна пропустить и большее количество данных, например 128 Кбайт, он передаст столько, сколько просит получатель (то есть 64 Кбайт). Окно управления потоком было описано ранее, поэтому в дальнейшем мы будем говорить только об окне перегрузки.

Современная схема контроля перегрузки была реализована в TCP во многом благодаря стараниям Ван Джекобсона (Van Jacobson, 1988). Это поистине захватывающая история. Начиная с 1986 года рост популярности Интернета привел к возникновению ситуаций, которые позже стали называть отказом сети из-за перегрузки (congestion collapse), — длительных периодов, во время которых эффективная пропускная способность резко падала (более чем в 100 раз) из-за перегрузки сети. Джекобсон (и многие другие) решил разобраться в ситуации и придумать конструктивное решение.

В результате Джекобсону удалось реализовать решение высокого уровня, которое состояло в использовании метода AIMD для выбора окна перегрузки. Особенно интересно то, что при всей сложности контроля перегрузки в TCP он смог добавить его в уже существующий протокол, не изменив ни одного формата сообщений. Благодаря этому новое решение можно было сразу применять на практике. Сначала Джекобсон заметил, что потеря пакетов является надежным сигналом перегрузки, даже несмотря на то, что эта информация и приходит с небольшим опозданием (уже после возникновения перегрузки). В конце концов, трудно представить себе маршрутизатор, который не удаляет пакеты при перегрузке. И в дальнейшем это вряд ли изменится. Даже когда буферная память будет исчисляться терабайтами, скорость сетей, скорее всего, также возрастет до нескольких терабит в секунду.

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

Все алгоритмы TCP для Интернета основаны на том предположении, что пакеты теряются из-за перегрузок. Поэтому они внимательно следят за тайм-аутами и пытаются обнаружить любые признаки проблемы подобно тому, как шахтеры следят за своими канарейками. Чтобы узнавать о потере пакетов вовремя и с высокой точностью, необходим хороший таймер повторной передачи. Мы уже говорили о том, как таймеры повторной передачи в TCP учитывают среднее значение и отклонение круговой задержки. Усовершенствование таких таймеров за счет учета отклонений стало важным шагом в работе Джекобсона. Если время ожидания повторной передачи выбрано правильно, TCP-отправитель может следить за количеством исходящих байт, нагружающих сеть. Для этого ему необходимо просто сравнить порядковые номера переданных и подтвержденных пакетов.

Теперь наша задача выглядит вполне простой. Все, что нам нужно, — это следить за размером окна перегрузки (с помощью порядковых номеров и номеров подтверждений) и изменять его, следуя правилу AIMD. Но, как вы уже догадались, на самом деле все гораздо сложнее. Первая сложность заключается в том, что способ отправки пакетов в сеть (даже за короткие промежутки времени) должен зависеть от сетевого пути. Иначе возникнет затор. Для примера рассмотрим хост с окном насыщения 64 Кбайт, подключенный к коммутируемой сети Ethernet со скоростью 1 Гбит/с. Если хост отправит целое окно за один раз, всплеск трафика может пойти через медленную ADSL-линию (1 Мбит/с). Этот трафик, прошедший по гигабитной линии за половину миллисекунды, на целых полсекунды парализует работу медленной линии, полностью блокируя такие протоколы, как VoIP. Так может работать протокол, нацеленный на создание перегрузок, но не на борьбу с ними.

Однако отправка небольших порций пакетов может оказаться полезной. На рис. 6.37 показано, что произойдет, если хост-отправитель, подключенный к быстрой линии (1 Гбит/с), отправит небольшую порцию пакетов (4) получателю, находящемуся в медленной сети (1 Мбит/с), которая является узким местом пути или его самой медленной частью. Сначала эти 4 пакета будут перемещаться по сети с той скоростью, с которой они будут отправлены. Затем маршрутизатор поместит их в очередь, так как они будут прибывать по высокоскоростной линии быстрее, чем передаваться по медленной линии. Но эта очередь не будет длинной, поскольку число пакетов, отправленных за один раз, невелико. Обратите внимание на то, что на рисунке пакеты, проходящие по медленной линии, выглядят длиннее, так как для их отправки требуется больше времени, чем по быстрой линии.

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

Рис. 6.37. Порция пакетов, переданная отправителем, и скорость прихода подтверждений

Здесь особенно важно следующее: подтверждения прибывают к отправителю примерно с той же скоростью, с которой пакеты могут передаваться по самому медленному каналу пути. Именно эта скорость и нужна отправителю. Если он будет передавать пакеты в сеть с такой скоростью, они будут перемещаться настолько быстро, насколько позволяет самый медленный канал, но зато не будут застревать в очередях на маршрутизаторах. Такая скорость называется скоростью прихода подтверждений (ack clock) и является неотъемлемой частью TCP. Этот параметр позволяет TCP выровнять трафик и избежать ненужных очередей на маршрутизаторах.

Вторая сложность состоит в том, что достижение хорошего рабочего режима по правилу AIMD в быстрых сетях потребует очень большого времени, если изначально выбрано маленькое окно перегрузки. Рассмотрим средний сетевой путь, позволяющий передавать трафик со скоростью 10 Мбит/с и круговой задержкой 100 мс. В данном случае удобно использовать окно перегрузки, равное произведению пропускной способности и времени задержки, то есть 1 Мбит или 100 пакетов по 1250 байт. Если изначально взять окно размером один пакет и увеличивать это значение на один пакет через интервал времени, равный круговой задержке, соединение начнет работать с нормальной скоростью только через 100 круговых задержек, то есть через 10 с. Это слишком долго. Теоретически мы могли бы начать с большего окна — скажем, размером 50 пакетов. Но для медленных линий это значение будет слишком большим. Тогда при отправке 50 пакетов за один раз возникнет затор — о таком сценарии мы говорили выше.

Решение, предложенное Джекобсоном, объединяет линейное и мультипликативное увеличение. При установлении соединения отправитель задает маленькое окно размером не более четырех сегментов. (Изначально начальный размер окна не превышал один сегмент, но впоследствии это значение на основании экспериментов было увеличено до четырех.) Подробнее об этом рассказывается в RFC 3390. Затем отправитель передает в сеть начальное окно. Получение пакетов подтвердится через время, равное круговой задержке. В каждом случае, когда подтверждение о получении сегмента приходит до срабатывания таймера повторной передачи, отправитель увеличивает окно перегрузки на длину одного сегмента (в байтах). Кроме того, если сегмент был получен, то в сети стало на один сегмент меньше. Поэтому в результате каждый подтвержденный сегмент позволяет отправить еще два сегмента. Таким образом, размер окна насыщения увеличивается вдвое через интервал времени, равный круговой задержке.

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

Рис. 6.38. Медленный старт с начальным окном перегрузки в один сегмент

Медленный старт хорошо работает для широкого диапазона значений скорости и круговой задержки. Чтобы регулировать скорость отправки в зависимости от сетевого пути, он использует скорость прихода подтверждений. Посмотрим на то, как подтверждения возвращаются от отправителя к получателю (рис. 6.38). Когда отправитель получает подтверждение, он увеличивает окно насыщения на единицу и сразу же передает в сеть два пакета. (Один пакет соответствует увеличению окна на единицу, а второй передается взамен пакета, прибывшего на место назначения и таким образом покинувшего сеть. В каждый момент времени число неподтвержденных пакетов определяется окном перегрузки.) Однако эти два пакета не обязательно придут на хостполучатель с таким же интервалом, с каким они были отправлены. Пусть, например, отправитель подключен к сети Ethernet мощностью 100 Мбит/с. На отправку каждого 1250-байтного пакета уходит 100 мкс. Поэтому интервал между пакетами может быть маленьким, от 100 мкс. Ситуация меняется, если путь следования пакетов проходит через ADSL-линию мощностью 1 Мбит/с. Теперь для отправки такого же пакета требуется 10 мс. Таким образом, минимальный интервал между пакетами возрастает, по меньшей мере, в 100 раз. Этот интервал так и останется большим, если только в какой-то момент пакеты не будут все вместе ожидать отправки в одном буфере.

На рис. 6.38 описанный эффект можно увидеть, если посмотреть на интервал прибытия пакетов на приемник. Этот интервал сохраняется при отправке подтверждений и, следовательно, при их получении отправителем. Если сетевой путь медленный, подтверждения приходят медленно (через время, равное круговой задержке). Если сетевой путь быстрый, подтверждения приходят быстро (опять же через время, равное круговой задержке). Отправитель должен просто учитывать скорость прихода подтверждений при отправке новых пакетов, — а это и делает алгоритм медленного старта.

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

Чтобы контролировать медленный старт, отправитель должен хранить в памяти пороговое значение для каждого соединения. Оно называется порогом медленного старта (slow start threshold). Изначально устанавливается произвольное высокое значение, не превышающее размер окна управления потоком, чтобы оно никак не ограничивало возможности соединения. Используя алгоритм медленного старта, TCP продолжает увеличивать окно перегрузки, пока не произойдет тайм-аут или размер окна перегрузки не превысит пороговое значение (или не заполнится окно получателя).

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

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

Аддитивное увеличение показано на рис. 6.39. Ситуация та же, что и для медленного старта. В конце каждого круга окно перегрузки отправителя увеличивается так, что в сеть может быть передан один дополнительный пакет. По сравнению с медленным стартом линейная скорость роста оказывается очень низкой. Для маленьких окон разница будет не очень существенной, но она станет ощутимой, если, к примеру, вам нужно увеличить окно на 100 сегментов.

Рис. 6.39. Аддитивное увеличение при начальном окне размером один сегмент

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

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

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

Этот эвристический метод получил название быстрый повтор ( fast retransmisson). Когда это происходит, порог медленного старта все равно устанавливается равным половине текущего окна перегрузки, как и в случае тайм-аута. Медленный старт можно начать заново, взяв окно размером в один сегмент. Новый пакет будет отправлен через время, за которое успеет прийти подтверждение для повторно переданного пакета, а также все остальные данные, переданные в сеть до обнаружения потери пакета.

На данный момент мы имеем алгоритм контроля перегрузки, работа которого проиллюстрирована на рис. 6.40. Эта версия называется TCP Tahoe в честь 4.2BSD Tahoe, выпущенного в 1988 году, где эти идеи были реализованы. Максимальный размер сегмента в данном примере равен 1 Кбайт. Сначала окно перегрузки было установлено равным 64 Кбайт, но затем произошел тайм-аут, и порог стал равным 32 Кбайт, а окно перегрузки — 1 Кбайт (передача 0). Затем размер окна перегрузки удваивается на каждом шаге, пока не достигает порога (32 Кбайт). Размер окна увеличивается каждый раз, когда приходит новое подтверждение, то есть не непрерывно, поэтому мы и имеем дискретный ступенчатый график. На каждом круге размер окна увеличивается на один сегмент.

Рис. 6.40. Медленный старт и последующее аддитивное увеличение в TCP Tahoe

Передачи на круге 13 оказываются неудачными (как и положено), и одна из них заканчивается потерей пакета. Отправитель обнаруживает это после получения трех дубликатов подтверждений. После этого потерянный пакет передается повторно, а пороговое значение устанавливается равным половине текущего размера окна (40 Кбайт пополам, то есть 20 Кбайт), и опять происходит медленный старт. До запуска нового медленного старта с окном в один сегмент проходит еще один круг, за который все ранее переданные данные, включая копию потерянного пакета, успевают покинуть сеть. Окно перегрузки снова увеличивается в соответствии с алгоритмом медленного старта до тех пор, пока оно не дойдет до порогового значения в 20 Кбайт. После этого рост размера окна опять становится линейным. Так будет продолжаться до следующей потери пакета, которая будет обнаружена с помощью дубликатов подтверждений или после наступления тайм-аута (или же до заполнения окна получателя).

Версия TCP Tahoe (в которой, кстати, используются хорошие таймеры повторной передачи) реализует работающий алгоритм контроля перегрузки, решающий проблему отказа сети из-за перегрузки. Джекобсон придумал, как сделать его еще лучше. Во время быстрой повторной передачи соединение работает с окном слишком большого размера, но скорость прихода подтверждений продолжает учитываться. Каждый раз, когда приходит дубликат подтверждения, велика вероятность того, что еще один пакет покинул сеть. Таким образом можно считать общее число пакетов в сети и продолжать отправку нового пакета при получении каждого дополнительного дубликата подтверждения.

Эвристический метод, реализующий эту идею, получил название быстрое восстановление (fast recovery). Это временный режим, позволяющий не останавливать учет скорости прихода подтверждений в тот момент, когда порогом медленного старта становится текущий размер окна или его половина (во время быстрой повторной передачи). Для этого считаются дубликаты подтверждений (включая те три, которые инициировали быструю повторную передачу) до тех пор, пока число пакетов в сети не снизится до нового порогового значения. На это уходит примерно половина круговой задержки. Начиная с этого момента для каждого полученного дубликата подтверждения отправитель может передавать в сеть новый пакет. Через один круг после быстрой повторной передачи получение потерянного пакета подтвердится. В этот момент дубликаты подтверждений перестанут приходить сплошным потоком, и алгоритм выйдет из режима быстрого восстановления. Окно перегрузки станет равным новому порогу медленного старта и начнет увеличиваться линейно.

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

Такое пилообразное движение показано на рис. 6.41. Данный метод используется в TCP Reno, который назван в честь выпущенного в 1990 году 4.3BSD Reno. По сути, TCP Reno — это TCP Tahoe с быстрым восстановлением. После начального медленного старта окно насыщения увеличивается линейно, пока отправитель не обнаружит потерю пакета, получив нужное количество дубликатов подтверждения. Потерянный пакет передается повторно, и далее алгоритм работает в режиме быстрого восстановления, который дает возможность не останавливать учет скорости прихода подтверждений до тех пор, пока не прибудет подтверждение о доставке повторно переданного пакета. После этого окно перегрузки принимает значение, равное новому порогу медленного старта, а не 1. Это продолжается неопределенно долго. Почти все время размер окна перегрузки близок к оптимальному значению произведения пропускной способности и времени задержки.

Механизмы выбора размера окна, использующиеся в TCP Reno, более чем на два десятилетия стали основой контроля перегрузки в TCP. В течение этих лет механизмы претерпели ряд незначительных изменений — в частности, появились новые способы выбора начального окна, были устранены неоднозначные ситуации. Усовершенствования коснулись и механизмов восстановления после потери двух или более пакетов. К примеру, версия TCP RenoNew использует номера частичных подтверждений, полученных после повторной передачи одного из потерянных пакетов, для восстановления другого потерянного пакета (Hoe, 1996) (см. RFC 3782). С середины 1990-х годов стали появляться варианты описанного выше алгоритма, основанные на других законах управления. К примеру, в системе Linux используется CUBIC TCP (Ha и др., 2008), а Windows включает вариант Compound TCP (Tan и др., 2006).

Рис. 6.41. Быстрое восстановление и пилообразный график для TCP Reno

Два более серьезных нововведения касаются реализаций TCP. Во-первых, сложность этого алгоритма заключается в том, что по дубликатам подтверждений необходимо определить, какие пакеты были потеряны, а какие — нет. Номер накопительного подтверждения не содержит такой информации. Простым решением стало использование выборочных подтверждений (SACK, Selective ACKnowledgement), в которых может содержаться до трех диапазонов успешно полученных байтов. Такая информация позволяет отправителю более точно определить, какие пакеты следует передать повторно, и следить за еще не доставленными пакетами.

При установлении соединения отправитель и получатель передают друг другу параметр SACK permitted, чтобы показать, что они могут работать с выборочными подтверждениями. Когда выборочные подтверждения включены, обмен данными происходит так, как показано на рис. 6.42. Получатель использует поле Номер подтверждения обычным способом — как накопительное подтверждение последнего по порядку полученного байта. Когда пакет 3 приходит к нему вне очереди (так как пакет 2 потерян), он отправляет SACK option для полученных данных вместе с накопительным подтверждением (дубликатом) для пакета 1. SACK option содержит информацию о диапазонах полученных байтов, которые располагаются после номера самого подтверждения. Первый диапазон — пакет, к которому относится дубликат подтверждения. Следующие диапазоны, если они есть, относятся к последующим блокам. Обычно используется не более трех диапазонов. К моменту прихода пакета 6 в выборочном

подтверждении используется уже два диапазона: первый указывает на получение пакетов 3 и 4, второй — на получение пакета 6 (вдобавок к пакетам, полученным до пакета 1). Основываясь на всех полученных SACK option, отправитель решает, какие пакеты следует передать повторно. В данном случае лучше всего взять пакеты 2 и 5.

Рис. 6.42. Выборочные подтверждения

Выборочные подтверждения содержат рекомендательную информацию. На самом деле, обнаружение потери пакетов по дубликатам подтверждений и изменение окна перегрузки происходят так, как было описано выше. Тем не менее выборочные подтверждения упрощают процесс восстановления в ситуациях, когда несколько пакетов теряются примерно в одно и то же время, так как с их помощью отправитель узнает, какие пакеты не дошли до адресата. Выборочные подтверждения применяются далеко не везде. О них рассказывается в RFC 2883, а контроль управления TCP с использованием выборочных подтверждений описан в RFC 3517.

Второе усовершенствование состоит в использовании явных уведомлений о перегрузке (ECN, Explicit Congestion Notification) в качестве дополнительного сигнала о перегрузке. Явные уведомления о перегрузке представляют собой механизм IP-уровня, позволяющий сообщать хостам о перегрузке (см. раздел 5.3.4). С его помощью TCP-приемник может получать сигналы о насыщении от IP.

Явные уведомления о перегрузке включены для TCP-соединения, если при установке этого соединения отправитель и получатель сообщили друг другу о том, что они могут использовать такие уведомления, с помощью битов ECE и CWR. В таком случае в заголовке каждого пакета с TCP-сегментом указано, что этот пакет может передавать явные уведомления о перегрузке. Тогда при угрозе перегрузки маршрутизаторы, поддерживающие такие уведомления, будут помещать сигналы о перегрузке в пакеты, имеющие соответствующие флаги, вместо того чтобы удалять пакеты, когда перегрузка действительно возникнет.

Если какой-то из прибывших пакетов содержит явное уведомление о перегрузке, TCP-приемник узнает об этом и с помощью флага ECE (ECN-эхо) сообщает отправителю о перегрузке. Отправитель подтверждает получение этого сигнала с помощью флага CWR (Окно перегрузки уменьшено).

На такие сигналы отправитель реагирует точно так же, как и на потерю пакетов. Но теперь результат выглядит лучше: перегрузка обнаружена, хотя ни один пакет не пострадал. Явные уведомления о перегрузке описаны в RFC 3168. Так как им требуется поддержка как хостов, так и маршрутизаторов, в Интернете они не очень широко используются.

Полный список механизмов контроля перегрузки в TCP и их работа описаны в RFC 5681.

6.5.11. Будущее TCP

TCP — «рабочая лошадка» Интернета — используется многими приложениями; с течением времени разработчики видоизменяют и дополняют этот протокол, стараясь добиться высокой производительности в различных сетях. На сегодняшний день существует много версий, каждая из которых добавляет что-то новое к классическим алгоритмам, описанным здесь; особенно это касается контроля перегрузки и устойчивости к сетевым атакам. По всей вероятности, TCP будет развиваться параллельно с Интернетом. Здесь мы рассмотрим два частных вопроса.

Во-первых, протокол TCP не решает проблем транспортной семантики, актуальных для многих приложений. К примеру, некоторые приложения хотят, чтобы границы передаваемых ими сообщений или записей сохранялись. Другие приложения хотят работать с группами взаимосвязанных сообщений — как, например, веб-браузер, загружающий несколько объектов с одного сервера. Некоторым приложениям нужны дополнительные возможности управления сетевыми путями. TCP со своим стандартным интерфейсом сокетов не в состоянии выполнить эти требования. В результате каждое приложение вынуждено самостоятельно решать проблемы, которые не по силам TCP. Это привело к возникновению новых протоколов со слегка измененным интерфейсом. Среди них SCTP (Stream Control Transmission Protocol, протокол передачи с управлением потоками), описанный в RFC 4960, и SST (Structured Stream Transport, иерархическая поточная транспортировка данных) (Ford, 2007). Но, как известно, всегда, когда кто-то предлагает изменить проверенный веками механизм, возникает два противоборствующих лагеря: «Пользователи хотят новых возможностей» и «Если ничего не сломано, не надо ничего чинить».

Второй вопрос касается контроля перегрузки. После такого подробного обсуждения различных механизмов и их усовершенствований этот вопрос мог показаться решенным. Это не так. Форма контроля перегрузки, описанная выше и достаточно популярная, использует в качестве сигнала о перегрузке потерю пакетов. При моделировании пропускной способности с помощью пилообразной схемы Padhye и его коллеги (1998) обнаружили, что при увеличении скорости частота потери пакетов должна резко снижаться. Чтобы добиться пропускной способности 1 Гбит/с при круговой задержке 100 мс и размере пакета 1500 байт, один пакет может теряться каждые 10 минут. Это соответствует частоте потери пакетов 2 х 10 - 8, а это очень мало. Потеря пакетов будет происходить слишком редко, так что этот параметр не может служить хорошим сигналом о перегрузке; число пакетов, потерянных по другой причине (например, ошибки при передаче происходят с частотой 10 - 7), может легко превысить это значение, что приведет к снижению пропускной способности.

До сих пор это не представлялось актуальным, но по мере того как сети становятся все более быстрыми, разработчики возвращаются к вопросу контроля перегрузки. Один из возможных вариантов — использовать новый алгоритм, в котором потеря пакетов вообще не учитывается. Несколько примеров было приведено в разделе 6.2. Сигналом перегрузки может быть, например, круговая задержка, которая растет при перегрузках, как в FAST TCP (Wei и др., 2006). Возможны и другие подходы; какой из них лучше — покажет время.

6.6. Вопросы производительности

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

К сожалению, понимание производительности сетей — это скорее искусство, чем наука. Теоретическая база, допускающая хоть какое-то практическое применение, крайне скудна. Лучшее, что мы можем сделать, это представить несколько практических методов, полученных в результате долгих экспериментов, а также привести несколько реально действующих примеров. Мы намеренно отложили эту дискуссию до того момента, когда будет изучен транспортный уровень в сетях TCP, чтобы иметь возможность иллюстрировать некоторые места примерами из TCP.

В следующих разделах мы рассмотрим основные аспекты производительности сети.

1.    Причины снижения производительности.

2.    Измерение производительности сети.

3.    Проектирование хостов для быстрых сетей.

4.    Быстрая обработка сегментов.

5.    Сжатие заголовка.

6.    Протоколы для протяженных сетей с высокой пропускной способностью (long fat networks).

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

6.6.1. Причины снижения производительности компьютерных сетей

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

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

Перегрузка может также возникать синхронно. Например, если сегмент содержит неверный параметр (например, номер порта назначения), во многих случаях получатель заботливо пошлет обратно сообщение об ошибке. Теперь рассмотрим, что случится, если неверный сегмент будет разослан широковещательным способом 10 000 машинам. Каждая машина может послать обратно сообщение об ошибке. Образовавшийся в результате широковещательный шторм (broadcast storm) может надолго остановить нормальную работу сети. Протокол UDP страдал от подобной проблемы, пока протокол ICMP не был изменен так, чтобы хосты воздерживались от отправки сообщений об ошибке в ответ на широковещательные сегменты UDP. Беспроводным сетям особенно важно не отвечать на непроверенные широковещательные пакеты, поскольку их пропускная способность ограничена.

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

Даже при отсутствии синхронной перегрузки и при достаточном количестве ресурсов производительность может снижаться из-за неверных системных настроек. Например, у машины может быть мощный процессор и много памяти, но недостаточно памяти выделено под буфер. В этом случае управление потоком данных замедлит получение сегментов и ограничит производительность. Такая проблема возникала для многих TCP-соединений, по мере того как Интернет становился более быстрым, а окно управления потоком было фиксированным (64 Кбайт).

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

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

6.6.2. Измерение производительности сети

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

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

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

Убедитесь, что выборка достаточно велика

Не следует ограничиваться единственным измерением какого-нибудь параметра — например, времени, необходимого для передачи одного сегмента. Повторите измерение, скажем, миллион раз и вычислите среднее значение. Начальные эффекты, например ситуации, когда после периода бездействия 802.16 NIC или кабельный модем получает зарезервированную пропускную способность, могут замедлить отправку первого сегмента, а помещение его в очередь увеличит разброс значений. Чем больше будет выборка, тем выше окажется точность оценки среднего значения и его среднеквадратичного отклонения. Погрешность может быть вычислена при помощи стандартных формул статистики.

Убедитесь, что выборка является репрезентативной

В идеале, следует повторить всю последовательность миллиона измерений параметров в различное время суток и в разные дни недели, чтобы заметить влияние различной загруженности системы на измеряемые параметры. Так, измерение перегрузки вряд ли принесет пользу, если эти измерения производить, когда перегрузки нет. Иногда результаты могут показаться на первый взгляд странными, как, например, наличие серьезных заторов в сети в 10, 11, 13 и 14 часов, но их отсутствие в полдень (когда все пользователи обедают).

В случае беспроводных сетей местоположение играет важную роль из-за распространения сигнала. Даже если узел, на котором выполняются измерения, находится рядом с беспроводным клиентом, он может не видеть некоторых пакетов, доступных клиенту, из-за различий в используемых антеннах. Измерения лучше проводить на хосте беспроводного клиента. Если это невозможно, необходимо выбрать несколько пунктов наблюдения и таким образом получить более полную картину (Mahajan и др., 2006).

Кэширование может сильно исказить ваши измерения

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

Буферирование пакетов может производить аналогичный эффект. Одна популярная TCP/IP-программа измерения производительности славилась тем, что сообщала, что протокол UDP может достичь производительности, значительно превышающей максимально допустимую для данной физической линии. Как это происходило? Обращение к UDP обычно возвращает управление сразу, как только сообщение принимается ядром системы и добавляется в очередь на передачу. При достаточном размере буфера время выполнения 1000 обращений к UDP не означает, что за это время все данные были переданы в линию. Большая часть их все еще находится в буфере ядра.

Следует быть абсолютно уверенным в том, что вы понимаете, как происходит кэширование и буферизация данных.

Убедитесь, что во время ваших тестов не происходит ничего неожиданного

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

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

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

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

Например, чтобы измерить время, необходимое для передачи одного сегмента, следует считывать показания системных часов (скажем, в миллисекундах) при входе и выходе из программы транспортного уровня. Если время, требуемое для передачи одного сегмента, равно 300 мкс, то измеряемая величина будет равна либо 0, либо 1 мс, что неверно. Тем не менее если повторить измерения миллион раз, сложить все значения и разделить на миллион, то полученное среднее значение будет отличаться от истинного значения менее чем на 1 мкс.

Будьте осторожны с экстраполяцией результатов

Предположим, вы что-нибудь измеряете (например, время ответа удаленного хоста), моделируя нагрузку сети от 0 (простой) до 0,4 (40 % максимальной пропускной способности). Пусть время ответа при отправке VoIP-пакета по сети 802.11 будет таким, как показано жирной линией на рис. 6.43. Может оказаться соблазнительным линейно экстраполировать полученную кривую (пунктир). Однако в действительности многие параметры в теории массового обслуживания содержат в качестве сомножителя 1/(1 - р), где р — нагрузка, поэтому истинная кривая зависимости будет больше походить на гиперболу, показанную штриховой линией, особенно при большой нагрузке. Таким образом, следует обращать внимание на влияние конкуренции, которое усиливается при большой нагрузке.

Рис. 6.43. Зависимость времени ответа от нагрузки

6.6.3. Проектирование хостов для быстрых сетей

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

В данном разделе мы рассмотрим несколько эмпирических правил, относящихся к программной реализации сетевых протоколов на хостах. Опыт показывает, что это, как правило, и является ограничивающим фактором производительности в случаях, когда сеть сама по себе работает быстро. Так происходит по двум причинам. Во-первых, сетевые карты (NIC) и маршрутизаторы разрабатываются так, чтобы они могли работать со скоростью сети. То есть они могут обрабатывать пакеты с той скоростью, с которой пакеты поступают. Во-вторых, нас интересует производительность, которая доступна приложениям. А она вычисляется не исходя из мощности канала, а исходя из пропускной способности и задержки, которые являются результатом работы сетевого и транспортного уровней.

Уменьшение накладных расходов из-за программного обеспечения улучшает производительность за счет повышения пропускной способности и снижения задержки. Оно также позволяет снизить затраты энергии, необходимые для передачи данных по сети, что актуально для мобильных компьютеров. Большинство этих идей известны разработчикам сетей уже много лет. Впервые они были записаны в явном виде Моголом (Mogul, 1993). Наше повествование во многом пересекается с его книгой. Другим источником по этой же теме является (Metcalfe, 1993).

Скорость центрального процессора важнее скорости сети

Длительные эксперименты показали, что почти во всех сетях накладные расходы операционной системы и протокола составляют основное время задержки сетевой операции. Например, теоретически минимальное время удаленного вызова процедур (RPC, Remote Procedure Call) в сети Ethernet мощностью 1 Гбит/с составляет 1 мкс, что соответствует минимальному запросу (512 байт), на который приходит минимальный (512-байтовый) ответ. На практике значительным достижением считается хотя бы какое-нибудь снижение накладных расходов, возникающих за счет программного обеспечения при вызове удаленной процедуры. Что происходит редко.

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

Уменьшайте число пакетов, чтобы уменьшить накладные расходы

Каждый сегмент содержит определенное количество накладных расходов (например, заголовок) и данные (например, полезную нагрузку). Оба эти компонента требуют пропускной способности. Также каждому из них требуется обработка (например, обработка заголовка и вычисление контрольной суммы). При отправке 1 млн байт побайтовые затраты времени процессора на обработку не зависят от размера сегмента. Однако при использовании 128-байтовых сегментов затраты на обработку заголовков будут в 32 раза выше, чем для сегментов размером 4 Кбайт. И эти затраты увеличиваются очень быстро.

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

Можно было бы сказать, что компьютер, как и человек, плохо справляется с многозадачностью. В основном поэтому возникает желание отправлять MTU-пакеты максимального размера, позволяющего избежать фрагментации. Механизмы наподобие алгоритма Нагля и метода Кларка также являются попытками избежать отправки маленьких пакетов.

Минимизируйте число операций с данными

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

Такое копирование может сильно снизить производительность, так как операции с памятью часто оказываются в десятки раз медленнее, чем операции с использованием только внутренних регистров. К примеру, если 20 % инструкций действительно связано с обращением к памяти (то есть данных нет в кэше), — а это вполне вероятная цифра при обработке входящих пакетов, — среднее время выполнения инструкции снизится в 2,8 раз (0,8 х 1 + 0,2 х 10). Аппаратные улучшения здесь не помогут. Проблема состоит в слишком большом числе операций копирования, выполняемых операционной системой.

Разумная операционная система постарается уменьшить число операций копирования, объединяя процессы обработки на разных уровнях. К примеру, TCP и IP обычно работают вместе («TCP/IP»), поэтому, когда обработка переходит от сетевого уровня к транспортному, копировать полезную нагрузку пакета не нужно. Еще один популярный прием состоит в том, чтобы выполнять несколько операций за один обход. Например, контрольные суммы часто вычисляются во время копирования данных (когда это действительно необходимо), и новое значение добавляется в конец.

Минимизируйте количество переключений контекста

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

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

Рис. 6.44. Четыре переключения контекста для обработки одного пакета, в случае если сетевой менеджер находится в пространстве пользователя

Лучше избегать перегрузки, чем бороться с уже возникшей перегрузкой

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

Избегайте тайм-аутов

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

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

6.6.4. Быстрая обработка сегментов

Теперь, когда мы поговорили об общих правилах, рассмотрим несколько методов, позволяющих ускорить обработку сегментов. Дополнительные сведения по этой теме см. в (Clark и др., 1989; Chase и др., 2001).

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

Хотя для перехода в состояние ESTABLISHED требуется передача последовательности специальных сегментов, но, как только это состояние достигнуто, обработка сегментов не вызывает затруднений, пока одна из сторон не начнет закрывать соединение. Начнем с рассмотрения посылающей стороны, находящейся в состоянии ESTABLISHED, когда должны отправляться данные. Для простоты мы предположим, что транспортная подсистема расположена в ядре, хотя те же самые идеи применимы и в случае, когда она представляет собой процесс, находящийся в пространстве пользователя, или набор библиотечных процедур в посылающем процессе. На рис. 6.45 отправляющий процесс эмулирует прерывание, выполняя базовую операцию SEND, и передает управление ядру. Прежде всего, транспортная подсистема проверяет, находится ли она в нормальном состоянии, то есть таком, когда установлено состояние ESTABLISHED, ни одна сторона не пытается закрыть соединение, посылается стандартный полный сегмент (без флага URGENT ) и у получателя достаточный размер окна. Если все эти условия выполнены, то никаких дополнительных проверок не требуется, и алгоритм транспортной подсистемы может выбрать быстрый путь. В большинстве случаев именно так и происходит.

В нормальной ситуации заголовки соседних сегментов почти одинаковы. Чтобы использовать этот факт, транспортная подсистема сохраняет в своем буфере прототип заголовка. В начале быстрого пути он как можно быстрее, пословно, копируется в буфер нового заголовка. Затем поверх перезаписываются все отличающиеся поля. Часто эти поля легко выводятся из переменных состояния — например, следующий порядковый номер сегмента. Затем указатель на заполненный заголовок сегмента и указатель на данные пользователя передаются сетевому уровню. Здесь может быть применена та же стратегия (на рис. 6.45 это не показано). Наконец, сетевой уровень передает полученный в результате пакет канальному уровню для отправки.

Рис. 6.45. Быстрый путь от отправителя до получателя показан жирной линией. Шаги обработки вдоль этого пути показаны затененными прямоугольниками

Чтобы увидеть, как работает этот принцип на практике, рассмотрим случай TCP/ IP. На рис. 6.46, а изображен TCP-заголовок. Поля, одинаковые для заголовков последующих сегментов в однонаправленном потоке, затенены. Все, что нужно сделать передающей транспортной подсистеме, это скопировать пять слов заголовка-прототипа в выходной буфер, заполнить поле порядкового номера (скопировав одно слово), сосчитать контрольную сумму и увеличить на единицу значение переменной, хранящей текущий порядковый номер. Затем она может передать заголовок и данные специальной IP-процедуре, предназначенной для отправки стандартного, максимального сегмента. Затем IP-процедура копирует свой заголовок-прототип из пяти слов (рис. 6.46, б) в буфер, заполняет поле Идентификатор и вычисляет контрольную сумму заголовка. Теперь пакет готов к передаче.

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

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

Рис. 6.46. TCP-заголовок (а); IP-заголовок (б). В обоих случаях затененные поля взяты

у прототипа без изменений

Затем сегмент проверяется на адекватность: соединение в состоянии ESTABLISHED, ни одна сторона не пытается его разорвать, сегмент является полным, специальные флаги не установлены, и порядковый номер соответствует ожидающемуся. Программа, выполняющая всю эту проверку, состоит из довольно значительного количества инструкций. Если все эти условия удовлетворяются, вызывается специальная процедура быстрого пути TCP-уровня.

Процедура быстрого пути обновляет запись соединения и копирует данные пользователю. Во время копирования она одновременно подсчитывает контрольную сумму, что уменьшает количество циклов обработки данных. Если контрольная сумма верна, запись соединения обновляется и отправляется подтверждение. Метод, реализованный в виде отдельной процедуры, сначала производящей быструю проверку заголовка, чтобы убедиться, что заголовок именно такой, какой ожидается, называется предсказанием заголовков (header prediction). Он применяется в большинстве реализаций протокола TCP. Использование этого метода оптимизации вместе с остальными, описанными в данном разделе, позволяет протоколу TCP достичь 90 % от скорости локального копирования из памяти в память, при условии, что сама сеть достаточно быстрая.

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

В программе таймеры обычно реализуются в виде связанного списка таймеров, отсортированного по времени срабатывания. Начальный элемент списка содержит счетчик, хранящий число минимальных интервалов времени (тиков — ticks), оставшихся до истечения периода ожидания. В каждом последующем элементе списка содержится счетчик, указывающий, через сколько тиков относительно предыдущего элемента списка истечет время ожидания данного таймера. Например, если таймеры сработают через 3, 10 и 12 тиков, счетчики списка будут содержать значения 3, 7 и 2 соответственно.

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

Если максимальное значение таймера ограничено и известно заранее, то может быть применен более эффективный метод. Здесь можно использовать массив, называющийся циклическим расписанием (рис. 6.47) (timing wheel). Каждое гнездо соответствует одному тику. Текущее время, показанное на рисунке, — T = 4. Таймеры должны сработать через 3, 10 и 12 тиков. Если новый таймер должен сработать через 7 тиков, то все, что нужно сделать, — задать значение указателя в гнезде 11 на новый список таймеров. Аналогично, если таймер, установленный на время T + 10, должен быть отключен, нужно всего лишь обнулить запись в гнезде 14. Обратите внимание на то, что массив на рис. 6.47 не может поддерживать таймеры за пределами T + 15.

Рис. 6.47. Циклическое расписание

При тике часов указатель текущего времени перемещается по циклическому расписанию вперед на одно гнездо. Если гнездо, на которое он указывает, не нулевое, обрабатываются все таймеры списка, на который указывает гнездо. Многочисленные варианты основной идеи обсуждаются в (Varghese и Lauck, 1989).

6.6.5. Сжатие заголовков

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

Чтобы эффективно использовать пропускную способность, заголовок протокола и полезная нагрузка должны занимать как можно меньше бит. Для полезной нагрузки этого можно достичь с помощью компактного кодирования информации — например, изображения лучше передавать в формате JPEG, а не в растровых форматах, или же в форматах документов со сжатием, таких как PDF. Также для этого необходимы механизмы кэширования прикладного уровня (такие как веб-кэш), уменьшающие число передач.

А что известно про заголовки протоколов? В беспроводных сетях на канальном уровне заголовки обычно занимают мало места, так как они изначально рассчитаны на низкую пропускную способность. Так, в 802.16 вместо длинных адресов используются короткие идентификаторы соединения. Однако протоколы более высоких уровней (такие как IP, TCP и UDP) универсальны для всех типов сетей, поэтому в них не используются компактные заголовки. На самом деле потоковая обработка, уменьшающая накладные расходы на программное обеспечение, часто приводит к еще большему увеличению длины заголовка (например, в IPv6 используются более разреженные заголовки, чем в IPv4).

Заголовки более высоких уровней могут сильно влиять на производительность. Рассмотрим, к примеру, процесс передачи VoIP-данных через IP, UDP и RTP. Этим протоколам требуется заголовок длиной 40 байт (20 байт для IPv4, 8 — для UDP, 12 — для RTP). В случае IPv6 ситуация еще хуже: 60 байт, включая 40-байтный заголовок IPv6. Эти заголовки могут становиться еще длиннее, потребляя более половины пропускной способности.

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

Сжатие заголовков можно реализовать эффективно, если учитывать формат протокола. Одна из первых схем была разработана Ван Джекобсоном (1990) и применялась для сжатия TCP/IP-заголовков при передаче по медленным последовательным каналам. Она позволяет уменьшить обычный 40-байтовый TCP/IP-заголовок в среднем до 3 байт. Если посмотреть на рис. 6.46, можно догадаться, на чем основан этот метод. Дело в том, что многие поля заголовка не меняются от пакета к пакету. К примеру, совсем не обязательно передавать одно и то же значение времени жизни пакета или один и тот же номер TCP-порта с каждым пакетом. Эти поля можно пропустить при передаче пакета и заполнить при получении.

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

С помощью сжатия заголовков можно добиться того, чтобы в протоколах высоких уровней заголовки были простыми, а при передаче пакета по каналам с низкой пропускной способностью использовалось компактное кодирование. Надежное сжатие заголовков (ROHC, Robust Header Compression) — современный вариант сжатия заголовков, который определен в RFC 5795 как фреймворк. В соответствии с замыслом разработчиков, он не реагирует на потерю пакетов в беспроводных каналах. Для каждого набора протоколов — например, IP/UDP/RTP — существует отдельный профиль. Сжатые заголовки передаются с помощью отсылки к контексту, то есть фактически к соединению; значения полей заголовков можно легко предсказать для пакетов данного соединения, но не для пакетов других соединений. При нормальной работе ROHC размер заголовков для IP/UDP/RTP снижается от 40 байт до 1-3 байт.

Хотя основная цель компрессии заголовков — уменьшение потребляемой пропускной способности, с помощью этого механизма можно также снизить задержку. Задержка складывается из задержки распространения, фиксированной для данного сетевого пути, и задержки передачи, которая зависит от пропускной способности и объема передаваемых данных. Например, канал мощностью 1 Мбит/с отправляет 1 бит за 1 мкс. Если мы имеем дело с передачей медиаданных по беспроводной сети, такой канал считается достаточно медленным, поэтому задержка передачи составляет существенную часть общей задержки, и стабильно низкая задержка крайне важна для качества обслуживания.

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

6.6.6. Протоколы для протяженных сетей с высокой пропускной способностью

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

Первая проблема заключается в том, что многие протоколы используют 32-разрядные порядковые номера. В прежние годы, когда типичная скорость выделенных линий между маршрутизаторами равнялась 56 Кбит/с, хосту, который постоянно выдавал бы данные в сеть на полной скорости, потребовалось бы больше недели на то, чтобы у него закончились порядковые номера. С точки зрения разработчиков TCP 232 считалось неплохим приближением к бесконечности, поскольку вероятность блуждания пакетов по сети в течение недели практически равна нулю. В Ethernet со скоростью 10 Мбит/с критическое время снизилось с одной недели до 57 минут. Это, конечно, гораздо меньше, но даже с таким интервалом еще можно иметь дело. Когда же Ethernet выдает в Интернет данные со скоростью 1 Гбит/с, порядковые номера закончатся примерно через 34 с. Это уже никуда не годится, поскольку максимальное время жизни пакета в Интернете равно 120 с. Внезапно оказалось, что 232 совершенно не подходит в качестве значения, приближенного к бесконечности, поскольку стало очевидно, что отправителю, посылающему достаточно много пакетов, придется повторять их порядковые номера в то время, как старые пакеты все еще будут блуждать по сети.

Проблема состоит в том, что многие разработчики протоколов просто предполагали, что время цикла пространства порядковых номеров значительно превосходит максимальное время жизни пакетов. Соответственно, в этих протоколах даже не рассматривалась сама возможность того, что старые пакеты еще могут находиться где-то в сети, когда порядковые номера опишут полный круг. В гигабитных сетях это предположение оказалось неверным. К счастью, оказалось возможным расширить эффективный порядковый номер, взяв в качестве старших битов метку времени, которая добавляется в TCP-заголовок каждого пакета в качестве дополнительного параметра. Этот механизм называется детектированием повторного использования порядковых номеров (PAWS, Protection Against Wrapped Sequence numbers). Он описан в RFC 1323.

Вторая проблема состоит в необходимости существенного увеличения окна управления потоком. Рассмотрим, например, процесс отправки 64 Кбайт данных из Сан-Диего в Бостон при размере буфера получателя в 64 Кбайт. Пусть скорость передачи данных в линии составляет 1 Гбит/с, а время прохождения сигнала в одну сторону, ограниченное скоростью света в стекле оптоволокна, равно 20 мс. Вначале (t = 0), как показано на рис. 6.48, а, канал пуст. Только 500 мкс спустя все сегменты попадут в канал (рис. 6.48, б). Первый сегмент оказывается где-то в окрестностях Броли, все еще в Южной Калифорнии. Тем не менее передатчик уже должен остановиться, пока он не получит в ответ новую информацию об окне.

Через 20 мс первый сегмент, как показано на рис. 6.48, в, достигнет Бостона, и в ответ будет передано подтверждение. Наконец, через 40 мс после начала операции первое подтверждение возвращается к отправителю, после чего передается следующая порция данных. Поскольку линия передачи использовалась всего 0,5 мс из 40 мс, эффективность ее использования составит около 1,25 %. Такая ситуация является типичной для работы старых протоколов по гигабитным линиям.

При анализе производительности сетей полезно обращать внимание на произведение пропускной способности и времени задержки (bandwidth-delay product). Пропускная способность канала (в битах в секунду) умножается на время прохождения сигнала в оба конца (в секундах). В результате получается емкость канала в битах.

В примере на рис. 6.48 произведение пропускной способности и времени задержки равно 40 млн бит. Другими словами, отправитель к моменту получения ответа успеет переслать 40 млн бит, если будет передавать с максимальной скоростью. Столько бит потребуется, чтобы заполнить канал в обоих направлениях. Таким образом, порция данных в полмиллиона бит составляет всего 1,25 % емкости канала, что и выражается в 1,25 % эффективности использования канала.

Рис. 6.48. Передача половины мегабита из Сан-Диего в Бостон: а — в момент времени t = 0; б — через 500 мкс; в — через 20 мс; г — через 40 мс

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

Третья проблема, связанная с предыдущей, состоит в том, что простые схемы повторной передачи, такие как протокол с возвращением на N блоков, плохо работают в линиях с большим значением произведения пропускной способности на задержку. Рассмотрим трансконтинентальную линию, работающую со скоростью 1 Гбит/с. Время прохождения сигнала в оба конца равно 40 мс. За это время отправитель успевает передать 5 Мбайт. Если обнаруживается ошибка, потребуется 40 мс, чтобы оповестить об этом отправителя. При использовании протокола с возвращением на N блоков отправителю потребуется повторять передачу не только поврежденного пакета, но также и до 5 Мбайт пакетов, переданных после поврежденного. Очевидно, что этот протокол использует ресурсы очень неэффективно. Поэтому необходимы более сложные механизмы, такие как метод выборочного повтора.

Суть четвертой проблемы состоит в том, что гигабитные линии принципиально отличаются от мегабитных — в длинных гигабитных линиях главным ограничивающим фактором является не пропускная способность, а задержка. На рис. 6.49 изображена зависимость времени, требующегося для передачи файла размером 1 Мбит по линии длиной в 4000 км, от скорости передачи. На скоростях до 1 Мбит/с время передачи

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

Рис. 6.49. Время передачи и подтверждения файла размером 1 Мбит по линии длиной 4000 км

Изображенная на рис. 6.49 зависимость демонстрирует ограничения сетевых протоколов. Она показывает, что протоколы с ожиданием подтверждений, такие как удаленный вызов процедур (RPC, Remote Procedure Call), имеют врожденное ограничение на производительность. Это ограничение связано со скоростью света. Никакие технологические прорывы в области оптики здесь не помогут (хотя могли бы помочь новые законы физики). Если в периоды времени, пока хост ждет ответа, гигабитная линия будет простаивать, она будет ничем не лучше простой мегабитной линии, а только дороже.

Пятая проблема заключается в том, что скорости передачи данных увеличиваются значительно быстрее, чем скорости обработки данных. (Обращение к разработчикам компьютеров: идите и побейте разработчиков средств связи! Мы рассчитываем на вас.) В 70-е годы объединенная сеть ARPANET работала на скорости 56 Кбит/с и состояла из компьютеров с производительностью около 1 MIPS (1 млн инструкций в секунду). Сравните эти цифры с цифрами для современных компьютеров, имеющих производительность 1000 MIPS и обменивающихся пакетами по гигабитной линии. Число инструкций на один байт уменьшилось более, чем в десять раз. Точные цифры зависят от времени и конкретной ситуации, но в итоге можно сказать следующее: у протокола осталось меньше времени на обработку пакетов, поэтому протоколы должны стать проще.

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

Проектируя, стремись увеличить скорость, а не оптимизировать пропускную способность.

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

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

Крайне важен в гигабитных сетях формат пакета. В заголовке должно быть как можно меньше полей — это позволит снизить время его обработки. Сами поля должны быть достаточно большими, чтобы нести в себе как можно больше полезной (служебной) информации. Кроме того, они не должны пересекать границы слов, тогда их будет проще обработать. В данном контексте под «достаточно большим» подразумевается такой размер, который исключает возникновение проблем зацикливания порядковых номеров при нахождении в сети старых пакетов, учитывает отсутствие у получателя возможности объявить реально доступный размер окна из-за слишком малого служебного поля размера окна и т. д.

Максимальный размер поля данных должен быть достаточно большим, чтобы снизить накладные расходы, возникающие за счет программного обеспечения, и обеспечить возможность эффективной работы сети. Размер пакета 1500 байт слишком мал для гигабитных сетей, поэтому гигабитная сеть Ethernet позволяет передавать сверхдлинные кадры размером до 9 Кбайт, а IPv6 поддерживает джамбограммы размером более 64 Кбайт.

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

Второй пример обратной связи — алгоритм медленного старта, разработанный Джекобсоном. Этот алгоритм проводит многочисленные пробы, пытаясь определить пропускную способность сети. В высокоскоростных сетях на проведение пяти-шести проб для определения ответной реакции сети тратится огромное количество сетевых ресурсов. Более эффективная схема состоит в резервировании ресурсов отправителем, получателем и сетью в момент установки соединения. Кроме того, заблаговременное резервирование ресурсов позволяет несколько снизить эффект неравномерности доставки (джиттер). Короче говоря, повышение скоростей передачи в сетях неумолимо заставляет разработчиков выбирать ориентированную на соединение (или близкую к этому) схему работы сети.

Еще одно полезное свойство протокола — возможность посылать нормальное количество данных вместе с запросом соединения. При этом можно сэкономить время одного запроса и ответа.

6.7. Сети, устойчивые к задержкам

Последний раздел мы посвятим новому виду транспорта, который, возможно, когда-нибудь станет важной частью Интернета. TCP и большинство других транспортных протоколов исходят из предположения о том, что между отправителем и получателем постоянно существует рабочий путь; в противном случае протокол дает сбой, и пакеты не доставляются. В некоторых сетях сквозной путь часто отсутствует. В качестве примера можно привести космическую сеть, в которой спутники LEO (Low-Earth Orbitнизкая околоземная орбита) попеременно находятся в зоне и вне зоны досягаемости наземных станций. Каждый конкретный спутник может установить связь с данной наземной станцией только в определенное время, а два спутника никогда не могут установить связь друг с другом даже через наземную станцию, так как один из них всегда находится вне зоны досягаемости этой станции. Другие примеры касаются подводных лодок, автобусов, мобильных телефонов и других устройств, оснащенных компьютерами, для которых связь является непостоянной из-за перемещений или экстремальных условий.

Тем не менее передача данных возможна и в сетях с непостоянной связью: эти данные могут задерживаться на узлах до тех пор, пока не появится рабочее соединение. Такой метод называется коммутацией сообщений. Сети, сконструированные по такому принципу, называются сетями, устойчивыми к задержкам (DTN, Delay-Tolerant Network), или распадоустойчивыми сетями (Disruption-Tolerant Network, DTN).

Работа над DTN началась в 2002 году, когда комиссией IETF была создана специальная исследовательская группа. Необходимость создания сетей, устойчивых к задержкам, возникла в неожиданном месте: при попытках отправлять пакеты в космосе. Космические сети вынуждены иметь дело с непостоянной связью и очень длинными задержками. Кевин Фолл заметил, что идеи, применимые к таким межпланетным интерсетям, вполне подойдут и для земных сетей, в которых непостоянная связь между узлами является обычным делом (Fall, 2003). Эта модель является обобщением Интернета, в котором при коммуникации возможны задержки и временное хранение данных.

Передача данных скорее похожа на доставку почтовой системой или по электронной почте, чем на коммутацию пакетов на маршрутизаторах2.

С 2002 года архитектура DTN была доработана, и сфера применения модели DTN расширилась. Представьте себе, к примеру, терабайтные массивы данных, полученных в результате экспериментов, из СМИ или с помощью веб-сервисов, которые необходимо передать в центры сбора данных, расположенные по всему миру. Операторам удобнее отправлять такой трафик во внепиковое время, чтобы использовать пропускную способность, за которую они заплатили, но которая не используется, и они готовы к определенным задержкам. Это напоминает резервное копирование, которое выполняется по ночам, когда другие приложения используют сеть не так активно. Если мы имеем дело с глобальными сервисами, проблема состоит в том, что в разных уголках мира внепиковое время разное. Периоды внепиковой пропускной способности могут почти не пересекаться, если центры сбора данных находятся, к примеру, в Перте и Бостоне (когда в одном из этих городов день, в другом — ночь).

Однако модели DTN предусматривают возможность хранения данных и большие задержки. С помощью такой модели массив данных можно сначала передать из Бостона в Амстердам во внепиковое время (так как время в них различается всего на 6 часов). Далее данные будут храниться в Амстердаме до того момента, когда их можно будет передать в Перт, используя внепиковую пропускную способность. В работе (Laoutaris и др., 2009) было установлено, что такая модель способна обеспечить хорошую пропускную способность при незначительных затратах, и эта пропускная способность часто вдвое превышает показатели обычной сквозной модели.

Далее мы рассмотрим архитектуру и протоколы DTN, разработанные IETF.

6.7.1. Архитектура DTN

Модель DTN предлагает отказаться от одного из предположений, на которых основан современный Интернет. Оно звучит так: в течение всего сеанса связи существует сквозной путь между отправителем и получателем. Когда это не так, обычные Интернет-протоколы не работают. Сети, устойчивые к задержкам, обходят проблему отсутствия сквозного пути с помощью архитектуры, основанной на коммутации сообщений (рис. 6.50). Кроме того, они приспособлены к передаче данных по каналам с низкой надежностью и большими задержками. Эта архитектура определена в RFC 4838.

В терминологии DTN сообщение называется посылкой. Узлы DTN оснащены запоминающими устройствами — как правило, с постоянной памятью (диски, флэш-память и т. д.). В них посылки хранятся до тех пор, пока нужный канал не активизируется; затем происходит отправка посылок. Каналы работают с перерывами. На рис. 6.50 изображено пять непостоянных каналов, которые в данный момент не работают, и два активных канала. Активный канал называется контактом. На рис. 6.50 также изображены две посылки, которые хранятся в узлах DTN, ожидая нужного контакта. По такой схеме пакеты передаются от источника в пункт назначения.

Рис. 6.50. Архитектура DTN

Такая схема очень похожа на то, что происходит с пакетами на маршрутизаторах. Однако здесь есть качественные отличия. На маршрутизаторах в Интернете ожидание в очереди длится несколько миллисекунд, в худшем случае — секунд. В узлах DTN посылки могут храниться часами — до тех пор, пока автобус не прибудет в город, самолет не приземлится, узел сенсорной сети не накопит солнечную энергию, необходимую для его работы, спящий компьютер не проснется и т. д. Эти примеры иллюстрируют и второе отличие: узлы могут перемещаться (вместе с автобусом или самолетом) вместе с хранящимися в них посылками, и это может играть ключевую роль в доставке данных; маршрутизаторы Интернета двигаться не могут. Чтобы описать весь процесс перемещения посылок, иногда используют термин «получение—перенос—отправка» («store—carry—forward»).

Для примера рассмотрим ситуацию, изображенную на рис. 6.51. Так протоколы DTN впервые использовались в космосе (Wood и др., 2008). Источник посылок — один из спутников LEO Международной системы мониторинга стихийных бедствий, который делает снимки Земли. Изображения должны приходить на пункт сбора данных. Но спутник имеет непостоянную связь с тремя наземными станциями. Двигаясь по орбите, он связывается ними по очереди. Таким образом, спутник, наземные станции и пункт сбора данных являются узлами DTN. По каждому контакту посылка (или часть посылки) передается наземной станции. Затем посылки доставляются на пункт сбора данных по транзитной наземной сети. На этом передача завершается.

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

Рис. 6.51. Использование DTN в космосе

В описании архитектуры DTN не рассматривается важный вопрос: как находить хорошие маршруты через узлы DTN. Хорошие маршруты зависят от архитектуры, которая описывает, когда следует отправлять данные и по каким направлениям (контактам). О некоторых контактах можно узнать заранее. Так, в нашем космическом примере заранее известно движение небесных тел. В эксперименте по использованию DTN в космосе заранее было известно время связи, а также то, что контакт с каждой наземной станцией длится от 5 до 14 минут и что пропускная способность нисходящей линии составляет 8,134 Мбит/с. С помощью этих сведений можно планировать передачу посылок с изображениями.

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

6.7.2. Протокол Bundle

Чтобы лучше понять, как работает DTN, мы рассмотрим протоколы IETF. DTN — это развивающийся тип сетей. В экспериментальных реализациях DTN используются самые разные протоколы. Для этого не обязательно использовать именно протоколы IETF. Но на их примере нам будет удобнее рассмотреть наиболее важные вопросы.

Стек протокола DTN показан на рис. 6.52. Основной протокол — это протокол Bundle; он описан в RFC 5050. Он принимает сообщения от приложения и передает их в виде одной или нескольких посылок с помощью операций получения—переноса— отправки принимающему узлу DTN. Как видно из рис. 6.52, он работает над уровнем TCP/IP. Иными словами, TCP/IP может использоваться в каждом из контактов для передачи посылок между узлами. Следовательно, возникает вопрос, к какому уровню относится протокол Bundle — транспортному или прикладному. Как и в случае с RTP, мы придерживаемся мнения, что, несмотря на более высокую позицию в иерархии, протокол Bundle предоставляет многим приложениям транспортные услуги, поэтому мы рассматриваем DTN в этой главе.

Рис. 6.52. Стек протоколов DTN

На рис. 6.52 также показано, что протокол Bundle может работать поверх других протоколов — например, UDP — или даже других интерсетей. К примеру, в космической сети каналы могут обладать большой задержкой. Круговая задержка между Землей и Марсом может составлять 20 минут (в зависимости от их взаимного расположения). Представьте себе, как здорово в таком канале будут работать подтверждения и повторные передачи, особенно для коротких сообщений! Вовсе не здорово. В такой ситуации необходим другой протокол, использующий коды с коррекцией ошибок. В сенсорных сетях, где ресурсы сильно ограничены, вместо TCP может использоваться более легковесный протокол.

Так как протокол Bundle является фиксированным, но в его задачи входит совместимость с различными транспортами, между сферами действия протоколов должен быть небольшой зазор. Эта идея привела к добавлению дополнительного уровня взаимодействия (convergence layer), как показано на рис. 6.52. На самом деле это просто связующий уровень, обеспечивающий совместную работу протоколов. По определению для каждого транспорта более низкого уровня должен существовать отдельный уровень взаимодействия. Уровни взаимодействия, позволяющие подключать новые и существующие протоколы, обычно можно найти в стандартах.

Формат сообщений протокола Bundle приведен на рис. 6.53. По названиям полей можно догадаться, чем занимается этот протокол.

Рис. 6.53. Формат сообщений протокола Bundle

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

Далее следуют адреса. И здесь уже есть кое-что интересное. Помимо полей идентификаторов Адрес назначения и Источник, мы видим идентификатор Ответственный хранитель. Ответственный хранитель — это сторона, обязанная следить за тем, чтобы пакет был доставлен. В Интернете эта роль обычно возложена на источник, так как именно он выполняет повторную передачу, если данные не доходят до пункта назначения. Но в DTN узел-источник не всегда находится на связи и, следовательно, не всегда может узнать, доставлены ли данные. Для решения этой проблемы в DTN используется процедура сдачи-приемки (custody transfer), при которой другой узел, расположенный ближе к получателю, принимает на себя ответственность за доставку данных. Например, если посылка временно хранится на самолете и будет передана позднее и в другом месте, самолет может стать ответственным хранителем этой посылки.

Второй интересный момент заключается в том, что эти идентификаторы не являются IP-адресами. Поскольку протокол Bundle работает с самыми разными транспортами и интерсетями, он использует свои собственные идентификаторы. Они больше похожи на имена высоких уровней, такие как URL веб-страниц, чем на адреса нижних уровней (IP). Такие идентификаторы дают сетям DTN возможности маршрутизации прикладного уровня, например доставки электронной почты или рассылки обновлений программного обеспечения.

Третий любопытный аспект — это то, как кодируются идентификаторы, так же как и идентификаторы в поле Уведомление, для диагностических сообщений. Все эти идентификаторы кодируются с помощью ссылок на поле Словарь переменной длины. Это позволяет использовать сжатие, когда узел ответственного хранителя или узел для диагностических сообщений совпадают с источником или адресом назначения. На самом деле разработчики формата сообщений стремились добиться как эффективности, так и возможности изменения длины поля, используя компактное представление для полей переменной длины. Последнее играет важную роль в беспроводных сетях, а также в сетях с ограниченными ресурсами, таких как сенсорные сети.

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

Первичный блок завершается полем Словарь. Далее идет блок полезной нагрузки. Он начинается с короткого поля Тип, в котором указано, что это полезная нагрузка, а за ним располагаются Флаги, в которых задаются параметры обработки. Далее следует поле Данные, перед которым располагается поле Длина. Наконец, за ними могут быть факультативные блоки — в частности, блок с параметрами безопасности.

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

6.8. Резюме

Транспортный уровень — это ключ к пониманию многоуровневых протоколов. Он предоставляет различные сервисы, наиболее важным из которых является сквозной, надежный, ориентированный на соединение поток байтов от отправителя к получателю. Доступ к нему предоставляется при помощи сервисных примитивов, позволяющих устанавливать, использовать и разрывать соединения. Общепринятый интерфейс транспортного уровня обеспечивается сокетами Беркли.

Транспортные протоколы должны обладать способностью управлять соединением в ненадежных сетях. Установка соединения осложняется возможностью существования дубликатов пакетов, которые могут появляться в самый неподходящий момент. Для борьбы с этими дубликатами при установке соединения применяется алгоритм «тройного рукопожатия». Разрыв соединения проще установки и тем не менее далеко не тривиален из-за наличия проблемы двух армий.

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

Контроль перегрузки должен справедливо распределять пропускную способность между конкурирующими потоками и следить за изменениями в использовании сети.

Закон управления AIMD позволяет получить эффективное и справедливое распределение.

Основными транспортными протоколами Интернета являются TCP и UDP. UDP — это протокол без установления соединения, который работает с IP-пакетами и занимается обеспечением мультиплексирования и демультиплексирования нескольких процессов с использованием единого IP-адреса. UDP может использоваться при клиент-серверных взаимодействиях, например при удаленном вызове процедур (RPC). Кроме того, на его основе можно создавать протоколы реального времени, такие как RTP.

Наиболее распространенным протоколом Интернета является TCP. Он обеспечивает надежный дуплексный поток байтов с контролем перегрузки. Он использует 20-байтный заголовок для всех сегментов. Оптимизации производительности протокола TCP было уделено много внимания. Для этого в нем применяются алгоритмы Нагля (Nagle), Кларка (Clark), Джекобсона (Jacobson), Карна (Kam) и др.

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

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

Вопросы

1.    В нашем примере транспортных примитивов, приведенных в табл. 6.1, LISTEN является блокирующим вызовом. Обязательно ли это? Если нет, объясните, как следует пользоваться неблокирующей базовой операцией. Какое преимущество это даст по сравнению со схемой, описанной в тексте?

2.    Базовые операции транспортного сервиса предполагают, что во время установки соединения две конечные точки ведут себя несимметрично: один конец (сервер) выполняет операцию LISTEN, а другой конец (клиент) — операцию CONNECT. Но в одноранговых приложениях (например, в приложениях для совместного доступа к файлам, таких как BitTorrent) все конечные точки считаются одинаковыми. Среди них нет серверов и клиентов. Как такое приложение может работать, используя базовые операции транспортного сервиса?

3.    В модели, лежащей в основе диаграммы состояний на рис. 6.3, предполагается, что пакеты могут теряться на сетевом уровне и поэтому должны подтверждаться индивидуально. Допустим, что сетевой уровень обеспечивает 100 % надежность доставки и никогда не теряет пакеты. Нужны ли какие-либо изменения в диаграмме состояний, показанной на рис. 6.3, и если да, то какие?

4.    В обеих частях листинга 6.1 значение SERVER_PORT должно быть одинаковым у клиента и у сервера. Почему это так важно?

5.    Посмотрите на пример с файловым сервером, приведенный в листинге 6.1. Может ли системный вызов клиента connect() закончиться неудачно по причине, отличной от переполнения очереди ожидания сервера? Считайте, что сеть идеальна.

6.    Чтобы решить, следует ли все время поддерживать сервер в активном состоянии, или лучше запускать его по требованию с помощью обрабатывающего сервера, можно использовать такой критерий: частоту использования данного сервера. Можете ли вы придумать другой критерий?

7.    Предположим, что используется управляемая часами схема генерирования начальных порядковых номеров с 15-разрядным счетчиком часов. Часы тикают раз в 100 мс, а максимальное время жизни пакета равно 60 с. Как часто должна производится ресинхронизация:

1)    в худшем случае?

2)    когда данные потребляют 240 порядковых номеров в минуту?

8.    Почему максимальное время жизни пакета T должно быть достаточно большим, чтобы гарантировать, что не только пакет, но и его подтверждение исчезли?

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

10.    Представьте себе обобщенную проблему n армий, в которой договоренность двух любых армий достаточна для победы. Существует ли протокол, позволяющий армиям синих выиграть?

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

12.    Представьте, что в сеть, изображенную на рис. 6.17, добавляется новый поток E, использующий путь через маршрутизаторы R1, R2 и R6. Как изменится распределение пропускной способности по максиминному критерию для пяти потоков?

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

14.    Существуют и другие политики, обеспечивающие равноправие при контроле перегрузки: аддитивное увеличение аддитивное уменьшение (AIAD), мультипликативное увеличение аддитивное уменьшение (MIAD), мультипликативное увеличение мультипликативное уменьшение (MIMD). Что вы можете сказать об их сходимости и стабильности?

15.    Зачем нужен протокол UDP? Разве не достаточно было бы просто позволить пользовательским процессам посылать необработанные IP-пакеты?

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

17.    Клиент посылает 128-байтный запрос на сервер, удаленный от него на 100 км, по оптоволокну со скоростью 1 Гбит/с. Какова эффективность линии во время выполнения удаленного вызова процедуры?

18.    Рассмотрите снова ситуацию, описанную в предыдущем вопросе. Вычислите минимально возможное время ответа для данной линии со скоростью 1 Гбит/с и для линии со скоростью 1 Мбит/с. Какой вывод можно сделать, исходя из полученных значений?

19.    Как в UDP, так и в TCP номера портов используются для идентификации принимающей подсистемы при доставке сообщения. Назовите две причины того, почему для этих протоколов были изобретены новые абстрактные идентификаторы (номера портов) и не использовались идентификаторы процессов, уже существовавшие на момент появления данных протоколов?

20.    Некоторые реализации RPC позволяют клиенту выбрать между реализацией с помощью UDP и реализацией с помощью TCP. В каком случае клиент выберет первый вариант, а в каком — второй?

21.    Рассмотрим две сети, N1 и N2, с одинаковой средней задержкой при передаче пакетов от источника A получателю D. В сети N1 задержка распределена равномерно с максимальным значением 10 с, а в сети N2 99 % пакетов имеют задержку менее одной секунды, но максимальная задержка может быть сколь угодно большой. Подумайте, как в таких ситуациях можно использовать RTP, если вы планируете передавать аудио/видео поток в режиме реального времени.

22.    Каков суммарный размер минимального MTU протокола TCP, включая накладные расходы TCP и IP, но не включая накладные расходы канального уровня?

23.    Фрагментация и дефрагментация дейтаграмм выполняется протоколом IP и невидима для протокола TCP. Означает ли это, что протокол TCP не должен беспокоиться о данных, приходящих в неверном порядке?

24.    RTP используется для передачи звукозаписей, по качеству соответствующих компакт-дискам. При этом для передачи одного отсчета каждого из стереоканалов используется пара 16-битных слов, передающихся 44 100 раз в секунду. Сколько пакетов в секунду должен уметь передавать RTP?

25.    Возможно ли поместить код RTP в ядро операционной системы наряду с UDP? Ответ поясните.

26.    Процессу хоста 1 был назначен порт р, а процессу хоста 2 — порт q. Может ли быть одновременно несколько соединений между этими двумя портами?

27.    На рис. 6.31 мы видели, что в дополнение к 32-разрядному полю Номер подтверждение в четвертом слове имеется бит ACK. Приносит ли он какую-либо пользу? Ответ поясните.

28.    Максимальный размер полезной нагрузки TCP-сегмента может быть равен 65 495 байт. Почему было выбрано такое странное число?

29.    Опишите два способа, которыми можно попасть в состояние SYNRCVD на рис. 6.33.

30.    Рассмотрите эффект использования алгоритма медленного старта в линии со значением времени прохождения сигнала в оба конца, равным 10 мс, без перегрузок. Размер окна получателя 24 Кбайт, а максимальный размер сегмента равен 2 Кбайт. Через какое время может быть послано полное окно?

31.    Предположим, окно перегрузки протокола TCP установлено на 18 Кбайт, когда происходит тайм-аут. Каким будет размер окна, если четыре последующих передачи будут успешными? Максимальный размер предполагается равным 1 Кбайт.

32.    Текущее значение оценки времени прохождения сигнала в оба конца протокола TCP RTT равно 30 мс, а следующие подтверждения приходят через 26, 32 и 24 мс. Каково будет новое значение RTT? Используйте а = 0,9.

33.    TCP-машина посылает окна по 65 535 байт по гигабитному каналу, в котором время прохождения сигнала в один конец равно 10 мс. Какова максимальная достижимая пропускная способность канала? Чему равна эффективность использования линии?

34.    Какова максимальная скорость, с которой хост может посылать в линию TCP-пакеты, содержащие 1500 байт полезной нагрузки, если максимальное время жизни пакета в сети равно 120 с? Требуется, чтобы порядковые номера не зацикливались. При расчете учитывайте накладные расходы на TCP, IP и Ethernet. Предполагается, что кадры Ethernet могут посылаться непрерывно.

35.    Чтобы исправить ограничения на адреса в IPv4, IETF приложила немало усилий и разработала IPv6, однако эта версия до сих пор внедряется неохотно. А к исправлению ограничений на адреса в TCP никто таких усилий не прилагает. Объясните, почему это так.

36.    Чему равна максимальная скорость передачи данных для каждого соединения, если максимальный размер сегмента равен 128 байт, максимальное время жизни сегмента равно 30 с и используются 8-разрядные порядковые номера сегментов?

37.    Предположим, вы измеряете время, необходимое для получения сегмента. Когда возникает прерывание, вы читаете показания системных часов в миллисекундах. После полной обработки сегмента вы снова читаете показания часов. В результате миллиона измерений вы получаете значения 0 мс 270 000 раз и 1 мс 730 000 раз. Какой вывод можно сделать на основании полученных результатов?

38.    Центральный процессор выполняет 1000 млн инструкций в секунду (1000 MIPS). Данные могут копироваться 64-разрядными словами. На копирование каждого слова требуется 10 инструкций. Может ли такая система управлять гигабитной линией, если каждый приходящий пакет должен быть скопирован четырежды? Для простоты предположим, что все инструкции, даже обращения к памяти, выполняются с максимальной скоростью, 1000 MIPS.

39.    Для решения проблемы повторного использования старых порядковых номеров пакетов, в то время как старые пакеты еще существуют, можно использовать 64-разрядные порядковые номера. Однако теоретически оптоволоконный кабель может обладать пропускной способностью до 75 Тбит/с. Каким следует выбрать максимальное время жизни пакетов, чтобы гарантировать отсутствие в сети будущего пакетов с одинаковыми номерами при скорости линий 75 Тбит/с и 64-разрядных порядковых номерах? Предполагается, что порядковый номер дается каждому байту, как в протоколе TCP.

40.    В результате расчета выяснилось, что гигабитная линия отправляет хосту 80 000 пакетов в секунду, оставляя ему только 6250 инструкций на их обработку — половина производительности процессора отдается приложениям. При этом предполагалось, что размер пакета должен быть 1500 байт. Выполните подсчеты заново для пакетов ARPANET (128 байт). В обоих случаях предполагается, что в размер пакета включены все накладные расходы.

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

42.    Рассчитайте произведение пропускной способности на задержку в следующих сетях:

1)    T1 (1,5 Мбит/с);

2)    Ethernet (10 Мбит/с);

3)    Т3 (45 Мбит/с);

4)    STS-3 (155 Мбит/с).

Предполагается, что RTT = 100 мс. Не забудьте о том, что в заголовке TCP на размер окна отводится 16-разрядное поле. Как это замечание отразится на результатах вычислений?

43.    Чему равно произведение пропускной способности на задержку для канала геостационарной спутниковой связи с пропускной способностью 50 Мбит/с? Если все пакеты имеют размер 1500 байт (включая накладные расходы), какого размера должно быть окно в пакетах?

44.    Файловый сервер, моделируемый листингом 6.1, далек от совершенства. Можно внести некоторые улучшения. Проделайте следующие изменения:

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

2)    Добавьте флаг -w в программу клиента, который позволил бы записывать файл на сервер.

45.    Почти все сетевые протоколы должны уметь работать с сообщениями. Если вы помните, протоколы передают сообщения путем добавления/отделения заголовков. Некоторые протоколы могут разбивать сообщение на несколько фрагментов, а потом восстанавливать его из этих фрагментов. Попробуйте разработать библиотеку управления сообщениями, реализовав поддержку создания нового сообщения, добавления/отделения заголовка, разбиения одного сообщения на два, объединения двух сообщений в одно и сохранения копии сообщения. Насколько это возможно, минимизируйте копирование данных из одного буфера в другой. Важно, чтобы эти операции работали только с указателями, не затрагивая данных, содержащихся в сообщении.

46.    Разработайте и реализуйте систему сетевого общения (чат), рассчитанную на несколько групп пользователей. Координатор чата должен располагаться по общеизвестному сетевому адресу, использовать для связи с клиентами протокол UDP, настраивать чат-серверы перед каждой сессией общения и поддерживать каталог чат-сессий. На каждую сессию должен выделяться один обслуживающий сервер. Для связи с клиентами сервер должен использовать TCP. Клиентская программа должна позволять пользователям начинать разговор, присоединяться к уже ведущейся дискуссии и покидать сессию. Разработайте и реализуйте код координатора, сервера и клиента.

Глава 7

Прикладной уровень

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

Разумеется, даже прикладной уровень нуждается в обслуживающих протоколах, с помощью которых осуществляется функционирование приложений. Соответственно, прежде чем начать рассмотрение самих приложений, мы изучим один из таких протоколов. Речь идет о службе имен доменов, DNS, обеспечивающей присвоение имен в Интернете. Затем мы рассмотрим три реально действующих приложения: электронную почту, Всемирную паутину и, наконец, мультимедиа. Мы закончим эту главу рассказом о доставке контента, в том числе и в равноранговых (пиринговых — peer-to-peer или сокращенно р2р) сетях.

7.1. Служба имен доменов DNS

Хотя программы теоретически могут обращаться к веб-страницам, почтовым ящикам и другим ресурсам по сетевым адресам компьютеров (например, IP), на которых хранится данная информация, пользователям тяжело запоминать такие адреса. Кроме того, размещение веб-страницы компании по адресу 128.111.24.41 будет означать, что в случае переезда сервера компании на новую машину новый IP будет необходимо сообщить всем заинтересованным лицам. Для отделения имен машин от их адресов было решено использовать понятные имена высокого уровня. Поэтому обратиться к веб-серверу компании можно по адресу www.cs.washington.edu. Тем не менее, так как сеть сама по себе понимает только числовые адреса, нужен механизм преобразования имен в сетевые адреса. В следующих разделах мы изучим, как производится это отображение в Интернете.

Когда-то давно во времена сети ARPANET соответствие между текстовыми и числовыми адресами просто записывалось в файле hosts.txt, в котором перечислялись все имена компьютеров и их IP-адреса. Каждую ночь все хосты получали этот файл с сайта, на котором он хранился. В сети, состоящей из нескольких сотен больших машин, работающих под управлением системы с разделением времени, такой подход оправдывал себя.

Однако еще за долго до того, как к сети были подключены миллионы компьютеров, всем стало ясно, что этот способ не сможет работать вечно. Во-первых, размер файла рано или поздно стал бы слишком большим. Однако, что еще важнее, если управление именами хостов не осуществлять централизованно, неизбежно возникновение конфликтов имен. В то же время представить себе централизованное управление именами всех хостов гигантской международной сети довольно сложно. Для разрешения всех этих проблем в 1983 году и была разработана служба имен доменов (DNS, Domain Name System). С тех пор она стала важнейшей частью Интернета.

Суть системы DNS заключается в иерархической схеме имен, основанной на доменах, и распределенной базе данных, реализующей эту схему имен. В первую очередь эта система используется для преобразования имен хостов в IP-адреса, но также может использоваться и в иных целях. Определение системы DNS дано в RFC 1034, 1035, 2181 и далее разработано во многих других.

В общих чертах система DNS применяется следующим образом. Для преобразования имени в IP-адрес прикладная программа обращается к библиотечной процедуре, называющейся распознавателем (resolver), передавая ей имя в качестве параметра. Мы видели пример распознавателя gethostbyname в листинге 6.1. Распознаватель посылает запрос, содержащий имя, локальному DNS-серверу, который ищет имя и возвращает соответствующий IP-адрес распознавателю, который, в свою очередь, передает этот адрес вызвавшей его прикладной программе. Запрос и ответ передаются как UDP-пакеты. Имея IP-адрес, программа может установить TCP-соединение с адресатом или послать ему UDP-пакеты.

7.1.1. Пространство имен DNS

Управление большим и постоянно изменяющимся набором имен представляет собой нетривиальную задачу. В почтовой системе на письмах требуется указывать (явно или неявно) страну, штат или область, город, улицу, номер дома, квартиру и фамилию получателя. Благодаря использованию такой иерархической схемы не возникает путаницы между Марвином Андерсоном, живущим на Мейн-стрит в Уайт-Плейнс, штат Нью-Йорк, и Марвином Андерсоном с Мейн-стрит в Остине, штат Техас. Система DNS работает аналогично.

Для Интернета основа иерархии именования разработана организацией под названием ICANN (Internet Corporation for Assigned Names and Numbers — интернет-корпорация по присвоению имен и адресов). ICANN была создана для этих целей в 1998 году, так как Интернет развился во всемирный экономический концерн. Интернет концептуально разделен на более чем 250 доменов верхнего уровня (top-level domains). Доменами называют в Интернете множество хостов, объединенных в логическую группу. Каждый домен верхнего уровня подразделяется на поддомены (subdomains), которые, в свою очередь, также могут состоять из других доменов и т. д. Все эти домены можно рассматривать в виде дерева, показанного на рис. 7.1. Листьями дерева являются домены, не разделяющиеся на поддомены (но состоящие из хостов, конечно). Такой конечный домен может состоять из одного хоста или может представлять компанию и содержать в себе тысячи хостов.

Рис. 7.1. Часть доменного пространства имен Интернета

Домены верхнего уровня разделяются на две группы: родовые домены и домены государств. К родовым относятся домены, перечисленные в табл 7.1, включая оригинальные домены, созданные 1980-х годах, и новые, введенные ICANN. В будущем будут добавляться новые базовые домены высшего уровня.

Таблица 7.1. Родовые домены верхнего уровня

Домен

Использование

Дата основания

Ограниченный?

com

Коммерческие цели

1985

Нет

edu

Образовательные учреждения

1985

Да

gov

Правительство

1985

Да

int

Международные организации

1985

Да

mil

Военные

1985

Да

net

Сетевые провайдеры

1985

Нет

org

Некоммерческие организации

1985

Нет

aero

Авиатранспорт

2001

Да

biz

Бизнес

2001

Нет

coop

Кооперативы

2001

Да

info

Информация

2002

Нет

museum

Музеи

2002

Да

name

Люди

2002

Нет

pro

Профессионалы

2002

Да

cat

Каталония

2005

Да

jobs

Занятость

2005

Да

mobi

Мобильные устройства

2005

Да

tel

Контактная информация

2005

Да

travel

Индустрия путешествий

2005

Да

xxx

Секс-индустрия

2010

Нет

За каждым государством в соответствии с международным стандартом ISO 3166 закреплен один домен государства. Интернационализированные доменные имена стран, в которых используется алфавит, отличный от латинского, были введены в 2010 году. Эти домены позволяют именовать хосты, используя арабские, кириллические, китайские и другие письменности.

Зарезервировать домен второго уровня, такой как имя_компании.сот, просто. Домены высшего уровня управляются регистраторами (registrars), назначенными ICANN. Для того чтобы получить имя, нужно просто обратиться к соответствующему регистратору (в данном случае com) и проверить, доступно ли желаемое имя и не является ли оно чьей-либо торговой маркой. Если все в порядке, заказчик регистрируется и за небольшую ежегодную абонентскую плату получает домен второго уровня.

Однако по мере коммерциализации и интернационализации Интернета появляется все больше спорных вопросов, особенно в отношении именования доменов. Эти споры захватывают и саму ICANN. Так, например, создание домена ххх заняло несколько лет и повлекло несколько судебных разбирательств. Размещение порно-контента на отдельном домене — это хорошо или плохо? (Некоторые и вовсе не хотели бы видеть в Интернете сайты с порнографическим содержанием, другие хотели бы разместить их все на один домен, чтобы было легче заблокировать их при помощи программ родительского контроля.) Некоторые домены являются самоорганизующимися, на других существуют ограничения и не всякий может получить имя (как показано в табл. 7.1). Но какие ограничения уместны? Взять хотя бы домен pro. Он предназначен для квалифицированных специалистов. Но кто является специалистом, а кто нет? Понятно, что доктора и адвокаты — это профессионалы, спору нет. А что делать со свободными фотографами, учителями музыки, заклинателями, водопроводчиками, парикмахерами, мусорщиками, татуировщиками, наемниками и проститутками? Имеют ли право квалифицированные представители всех этих и многих других профессий получать домены pro? Кто должен это определять?

Кроме того, на именах можно зарабатывать. Так страна Тувалу сдала в аренду права на свой домен tv за $50 млн благодаря тому, что код страны отлично подходит для рекламы телевизионных сайтов. Практически все общеупотребительные английские слова используются в качестве имен поддоменов com, вместе с наиболее частыми опечатками. Попробуйте набрать какое-нибудь слово, касающееся домашнего хозяйства, животных, растений, частей тела и т. д. У самой практики регистрации доменных имен с целью их дальнейшей продажи заинтересованной стороне даже есть название — ки-берсквоттинг (cybersquatting). Многие компании, которые оказались не достаточно шустрыми в этом вопросе, обнаружили, что самые очевидные доменные имена уже заняты, когда началась эра Интернета и они попытались зарегистрироваться. В общем и целом, если не были нарушены права на товарный знак и не было предпринято мошеннических действий, в отношении имен работает правило «первым запросил — первым получил». Тем не менее политика в отношении разрешения споров по поводу имен все еще не до конца устоялась.

Имя каждого домена, подобно полному пути к файлу в файловой системе, состоит из пути от этого домена до (безымянной) вершины дерева. Компоненты пути разделяются точками. Так, домен технического отдела корпорации Cisco может выглядеть как eng.cisco.com, а не так, как это принято в стиле UNIX (/com/cisco/eng). Следует отметить, что из-за такой иерархической системы наименования eng.cisco.com не конфликтует с потенциальным использованием имени eng в домене eng.washington.edu, где он может обозначать факультет английского языка Вашингтонского университета.

Имена доменов могут быть абсолютными и относительными. Абсолютное имя домена всегда оканчивается точкой (например, eng.cisco.com.), тогда как относительное имя — нет. Для того чтобы можно было единственным образом определить истинные значения относительных имен, они должны интерпретироваться в некотором контексте. В любом случае именованный домен означает определенный узел дерева и все узлы под ним.

Имена доменов нечувствительны к изменению регистра символов. Так, например, edu, Edu и EDU означают одно и то же. Длина имен компонентов может достигать 63 символов, а длина полного пути не должна превосходить 255 символов.

В принципе, новые домены могут добавляться в дерево с использованием как родового домена, так и домена, обозначающего страну. Например, cs.wasington.edu можно без проблем поместить в домен us под именем cs.wasington.wa.us. На практике, однако, почти все организации в США помещаются под родовыми доменами, тогда как почти все организации за пределами США располагаются под доменами своих государств. Не существует каких-либо правил, запрещающих регистрацию под несколькими доменами верхнего уровня. Большие компании зачастую именно так и поступают (например, sony.com, sony.net и sony.nl).

Каждый домен управляет распределением доменов, расположенных под ним. Например, в Японии домены ac.jp и co.jp соответствуют американским доменам edu и com. В Голландии подобное различие не используется, и все домены организаций помещаются прямо под доменом nl. В качестве примера приведем имена доменов факультетов вычислительной техники («компьютерных наук» — computer science) трех университетов.

1.    cs.wasington.edu (Вашингтонский университет, США)

2.    cs.vu.nl (университет Врийе, Нидерланды)

3.    cs.keio.ac.jp (университет Кейо, Япония)

Для создания нового домена требуется разрешение домена, в который он будет включен. Например, если в Вашингтонском университете образовалась группа VLSI, которая хочет зарегистрировать домен vlsi.cs.wasington.edu, ей нужно разрешение от того, кто управляет доменом cs.wasington.edu. Аналогично, если создается новый университет, например, университет Северной—Южной Дакоты, он должен попросить менеджера домена edu присвоить их домену имя unsd.edu (если оно еще не занято). Таким образом, удается избежать конфликта имен, а каждый домен отслеживает состояние всех своих поддоменов. После того как домен создан и зарегистрирован, в нем могут создаваться поддомены, например cs.unsd.edu, для чего уже не требуется разрешения вышестоящих доменов.

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

7.1.2. Записи ресурсов доменов

У каждого домена, независимо от того, является ли он одиноким хостом или доменом верхнего уровня, может быть набор ассоциированных с ним записей ресурсов (resource records). Эти записи являются базой данных DNS. Для одинокого хоста запись ресурсов чаще всего представляет собой просто его IP-адрес, но существует также много других записей ресурсов. Когда распознаватель передает имя домена DNS-серверу, то, что он получает обратно, представляет собой записи ресурсов, ассоциированные с его именем. Таким образом, истинное назначение системы DNS заключается в преобразовании доменных имен в записи ресурсов.

Запись ресурса состоит из пяти частей. Хотя для эффективности они часто перекодируются в двоичную форму, в большинстве описаний записи ресурсов представлены в виде ASCII-текста, по одной строке на запись ресурса. Мы будем использовать следующий формат:

Domain_name Time_to_live Class Type Value

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

Поле Time__to_live (время жизни) указывает, насколько стабильно состояние записи. Редко меняющимся данным присваивается высокое значение этого поля, например, 86 400 (число секунд в сутках). Непостоянная информация помечается небольшим значением, например, 60 (1 минута). Мы вернемся к этому вопросу позднее, когда будем обсуждать кэширование.

Третьим полем каждой записи является поле Class (класс). Для информации Интернета значение этого поля всегда равно IN. Для прочей информации применяются другие коды, однако на практике они встречаются редко.

Поле Type (тип) означает тип DNS-записи. Их существует довольно много. Важные типы записей перечислены в табл. 7.2.

Запись SOA (Start Of Authority — начальная точка полномочий) сообщает имя первичного источника информации о зоне сервера имен (описанного ниже), адрес электронной почты его администратора, уникальный порядковый номер, различные флаги и тайм-ауты.

Самой важной является запись A (Address — адрес). Она содержит 32-разрядный IPv4-адрес интерфейса для хоста. У соответствующей записи AAAA («quad A» — «четыре A») есть 128-разрядный IPv6-адрес. У каждого хоста в Интернете должен быть по меньшей мере один IP-адрес, чтобы другие машины могли с ним общаться. На некоторых хостах может быть одновременно установлено несколько сетевых соединений. В этом случае им требуется по две или более записи типа A или AAAA. Соответственно, DNS может выдавать несколько адресов на одно имя.

Запись MX является стандартной. В ней указывается имя хоста, готового принимать почту для указанного домена. Дело в том, что не каждая машина может заниматься приемом почты. Если кто-нибудь хочет послать письмо на адрес, например bill@ microsoft.com, то отправляющему хосту нужно будет вначале найти почтовый сервер на microsoft.com. Запись MX может помочь в этих поисках.

Таблица 7.2. Основные типы записей ресурсов DNS

Тип

Смысл

Значение

SOA

Начальная запись зоны

Параметры для этой зоны

A

IPv4-адрес хоста

Целое число, 32 двоичных разряда

AAAA

^6-адрес хоста

Целое число, 128 двоичных разрядов

MX

Обмен почтой

Приоритет, с которым домен желает принимать электронную почту

NS

Сервер имен

Имя сервера для этого домена

CNAME

Каноническое имя

Имя домена

PTR

Указатель

Псевдоним IP-адреса

SPF

Правила отправки почты

Правила отправки почты, закодированные в текстовом виде

SRV

Сервис

Хост, предоставляющий данный сервис

TXT

Текст

Не интерпретируемый ASCII-текст

Еще один важный тип записи — это NS. Запись NS содержит информацию о сервере имени для домена или поддомена. Это хост, на котором содержится копия базы данных для домена. Он используется в процессе поиска имени, поэтому мы вкратце опишем этот процесс.

Записи CNAME позволяют создавать псевдонимы. Представим себе, что человек, знакомый в общих чертах с формированием имен в Интернете, хочет послать сообщение пользователю paul на отделении вычислительной техники Массачусетского технологического института (M.I.T.). Он может попытаться угадать нужный ему адрес, составив строку [email protected]. Однако этот адрес работать не будет, так как домен отделения вычислительной техники Массачусетского технологического института на самом деле называется csail.mit.edu. Таким образом, для удобства тех, кто этого не знает, M.I.T. может создать запись CNAME, позволяющую обращаться к нужному домену по обоим именам. Такая запись будет иметь следующий вид: cs.mit.edu 86400 IN CNAME csail.mit.edu

Как и CNAME, запись PTR указывает на другое имя. Однако в отличие от записи CNAME, являющейся, по сути, макроопределением (то есть механизмом замены одной строки другой), PTR представляет собой обычный тип данных DNS, интерпретация которого зависит от контекста. На практике запись PTR почти всегда используется для ассоциации имени с IP-адресом, что позволяет по IP-адресу находить имя соответствующей машины. Это называется обратным поиском (reverse lookups).

Запись SRV — это новый тип, позволяющий определять хост для искомого сервиса в домене. Например, веб-сервер для cs.wasington.edu может быть определен как cockatoo.cs.wasington.edu. Данная запись является расширенным вариантом записи MX, которая выполняет ту же задачу в рамках почтовых сервисов.

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

Последние в списке, TXT-записи изначально предназначались для того, чтобы позволить доменам идентифицировать себя произвольным образом. Сегодня с их помощью обычно кодируется информация, предназначенная для считывания машиной, обычно это SPF-информация.

Наконец, последнее поле записи ресурса — это поле Value (значение) — может быть числом, именем домена или текстовой ASCII-строкой. Смысл поля зависит от типа записи. Краткое описание поля Value для каждого из основных типов записей дано в табл. 7.2.

Пример информации, хранящейся в базе данных DNS домена, приведен в листинге 7.1. В нем показана часть (гипотетической) базы данных домена cs.vu.nl, представленного также в виде узла дерева доменов на рис. 7.1. В базе данных содержится семь типов записей ресурсов.

Листинг 7.1. Часть возможной базы данных домена cs.vu.nl

; Официальная

информация

для cs.vu.nl

cs.vu.nl.

86400

IN

SOA star boss (9527,7200,7200,241920,86400)

cs.vu.nl.

86400

IN

MX 1 zephyr

cs.vu.nl.

86400

IN

MX 2 top

cs.vu.nl.

86400

IN

NS star

star

86400

IN

A 130.37.56.205

zephyr

86400

IN

A 130.37.20.10

top

86400

IN

A 130.37.20.11

www

86400

IN

CNAME star.cs.vu.nl

ftp

86400

IN

CNAME zephyr.cs.vu.nl

flits

86400

IN

A 130.37.16.112

flits

86400

IN

A 192.31.231.165

flits

86400

IN

MX 1 flits

flits

86400

IN

MX 2 zephyr

flits

86400

IN

MX 3 top

rowboat

IN

A

130.37.56.201

IN

MX

1 rowboat

IN

MX

2 zephyr

little-sister

IN

A

130.37.62.23

laserjet

IN

A

192.31.231.216

В первой не закомментированной строке листинга 7.1 дается основная информация о домене, которая в дальнейшем нас интересовать не будет. Следующие две строки определяют два хоста, с которыми следует связаться в первую очередь при попытке доставить электронную почту, посланную по адресу [email protected]. Хост по имени zephyr (специальная машина) следует опросить первым. В случае неудачи следует попробовать доставить письмо машине по имени top. В следующей строке определен сервер имен для домена star.

После пустой строки, добавленной для удобства чтения, следуют строки, сообщающие IP-адреса для star, zephyrи top. Далее следует псевдоним www.cs.vu.nl, позволяющий не обращаться к какой-то конкретной машине. Создание этого псевдонима позволяет домену cs.vu.nlизменять свой WWW-сервер, не меняя адреса, по которому пользователи смогут продолжать к нему обращаться. То же справедливо и для домена ftp.cs.vu.nl— FTP-сервера.

В секции, предназначенной для машины flits, перечислены два IP-адреса и три возможных варианта адреса для обработки почты, отосланной на flits.cs.vu.nl.В первую очередь, естественно, следует пытаться доставить письмо самому компьютеру flits. Но если этот хост выключен, следует продолжать попытки, обращаясь к хостам zephyrи top.

Следующие три строки содержат типичные записи для компьютера, в данном случае для rowboat.cs.vu.nl. Хранящаяся в базе данных информация содержит IP-адрес, а также имена первого и второго хостов для доставки почты. Следом идет запись о машине, которая сама не способна получать почту. Последняя строка, вероятно, описывает лазерный принтер, подключенный к Интернету.

7.1.3. Серверы имен

Теоретически один сервер мог бы содержать всю базу данных DNS и отвечать на все запросы к ней. На практике этот сервер оказался бы настолько перегруженным, что был бы просто бесполезным. Более того, если бы с ним когда-нибудь что-нибудь случилось, то весь Интернет не работал бы.

Чтобы избежать проблем, связанных с хранением всей информации в одном месте, пространство имен DNS разделено на непересекающиеся зоны (zones). Один возможный способ разделения пространства имен, показанного на рис. 7.1, на зоны изображен на рис. 7.2. Каждая очерченная зона содержит часть общего дерева доменов.

Расстановка границ зон целиком зависит от администратора зоны. Это решение основывается на том, сколько серверов имен требуется в той или иной зоне. Например, на рис. 7.2 у Вашингтонского университета есть зона для washington.edu, управляющая доменом eng.washington.edu, но не доменом cs.washington.edu, расположенным в отдельной зоне со своими серверами имен. Подобное решение может быть принято, когда факультет английского языка не хочет управлять собственным сервером имен, но этого хочет факультет вычислительной техники.

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

Рис. 7.2. Часть пространства имен DNS, разделенная на очерченные зоны

Процесс поиска адреса по имени называется разрешением имен (name resolution). Распознаватель обращается с запросом разрешения имени домена к локальному серверу имен. Если искомый домен относится к сфере ответственности данного сервера имен, как, например, домен top.cs.vu.nl подпадает под юрисдикцию домена cs.vu.nl, тогда данный DNS-сервер сам отвечает распознавателю на его запрос, передавая ему авторитетную запись (authoritative record) ресурса. Авторитетной называют запись, получаемую от официального источника, хранящего данную запись и управляющего ее состоянием. Поэтому такая запись всегда считается верной, в отличие от кэшируемых записей (cached records), которые могут устаревать.

Однако что происходит, если домен удаленный, как, например, в случае, когда flits.cs.vu.nl пытается найти IP-адрес для robot.cs.washington.edu в Вашингтонском университете? В этом случае, если в кэше нет информации о запрашиваемом домене, доступном локально, сервер имен посылает удаленный запрос. Поясним данный процесс на примере, показанном на рис. 7.3. На первом шаге (обозначен «1») посылается запрос локальному серверу имен. Этот запрос содержит имя искомого домена, тип (Л) и класс (IN).

Рис. 7.3. Пример поиска распознавателем имени удаленного хоста в десяти шагах

На следующем шаге посылается запрос на один из корневых серверов имен (root name servers), находящихся на вершине иерархии. На этих серверах имен хранится информация о каждом домене высшего уровня. Этот запрос показан как шаг 2 на рис. 7.3. Чтобы связаться с корневым сервером, на каждом сервере имен должна быть информация об одном или более корневых серверах имен. Обычно эта информация представлена в файле системной конфигурации, который загружается в кэш DNS, когда запускается сервер DNS. Он является просто списком записей NS и соответствующих записей А.

Существует 13 корневых серверов DNS, которые называются незамысловато — от a-root-servers.net до m.root-servers.net. Каждый корневой сервер логически мог бы быть отдельным компьютером. Однако так как весь Интернет зависит от корневых серверов, они являются мощными машинами, а информация, хранящаяся на них, неоднократно дублируется. Большинство серверов расположено в различных географических точках, и доступ к ним осуществляется посредством адресации любому устройству из группы, при этом пакет доставляется на ближайший адрес (мы описали адресацию любому устройству группы в пятой главе). Дублирование информации повышает надежность и производительность.

Маловероятно, чтобы этот корневой сервер имен знал адрес машины в Вашингтонском университете. Скорее всего, он даже не знает адреса сервера имен самого университета, однако он должен знать сервер имен домена edu, на котором расположен cs.washington.edu. Он возвращает имя и IP-адрес для части ответа на третьем шаге.

Далее локальный сервер имен продолжает этот сложный путь. Он направляет запрос серверу имен edu (a.edu-servers.net), который выдает имя сервера Вашингтонского университета. Этот процесс проиллюстрирован шагами 4 и 5. Теперь мы уже подошли ближе. Локальный сервер имен отсылает запрос на сервер имен Вашингтонского университета (шаг 6). Если искомое имя домена находится на факультете английского языка, будет получен ответ, так как зона университета этот факультет охватывает. Но факультет вычислительной техники решил запустить собственный сервер имен. Запрос возвращает имя и IP-адрес сервера имен факультета вычислительной техники Вашингтонского университета (шаг 7).

Наконец, локальный сервер имен запрашивает сервер имен факультета вычислительной техники Вашингтонского университета (шаг 8). Этот сервер отвечает за домен cs.washington.edu, так что он должен выдать ответ. В итоге окончательный ответ возвращается (шаг 9), и локальный сервер имен передает его на flits.cs.vu.nl (шаг 10). Имя получено.

Вы можете изучить этот процесс, используя стандартные программы типа dig, которые установлены на большинстве UNIX-систем. Например, напечатав dig @a.edu-servers.net robot.cs.washington.edu

вы отправите запрос robot.cs.washington.edu на сервер имен a.edu-servers.net и получите распечатку результата. Так вы увидите информацию, которую мы получили на четвертом шаге в нашем примере, и узнаете имя и IP-адреса серверов имен Вашингтонского университета.

В этом длинном сценарии есть три технических момента, требующих пояснения. Во-первых, на рис. 7.3 используется два разных механизма запроса. Когда хост flits. cs.vu.nl отсылает запрос на локальный сервер имен, этот сервер выполняет запрос от имени flits, пока не получит ответ, который можно будет вернуть. Он не возвращает частичных ответов. Они могут быть полезными, но в запросе о них нет ни слова. Этот механизм называется рекурсивным запросом (recursive query).

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

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

Второе, на чем стоит заострить внимание, — это кэширование. Все ответы, в том числе все возвращенные частичные ответы, сохраняются в кэше. Таким образом, если другой хост cs.vu.nl запрашивает robot.cs.washington.edu, ответ будет уже известен. Более того, если хост запрашивает другой хост на том же домене, например galah. cs.washington.edu, ответ может быть отослан напрямую на сервер имен, который отвечает за это имя. Сходным образом запросы на другие домены на washington.edu могут начинаться напрямую с сервера имен washington.edu. Использование ответов, сохраненных в кэше, серьезно сокращает количество шагов в запросе и повышает производительность. Сценарий, который мы набросали, на самом деле, является худшим из возможных вариантов, так как в кэше нет полезной информации.

Однако ответы, сохраненные в кэше, не являются авторитетными, так как изменения в домене cs.washington.edu не будут распространяться автоматически на все кэши, в которых может храниться копия этой информации. По этой причине записи кэша обычно долго не живут. В каждой записи ресурса присутствует поле Time_to_live. Оно сообщает удаленным серверам, насколько долго следует хранить эту запись в кэше. Если какая-либо машина сохраняет постоянный адрес годами, возможно, будет достаточно надежно хранить эту информацию в кэше в течение одного дня. Для более непостоянной информации, вероятно, более осмотрительно удалять все записи через несколько секунд или одну минуту3.

Третий момент, на котором нам хотелось бы заострить внимание, — это протокол транспортного уровня, который используется для запросов и ответов, UDP. DNS-сообщения посылаются в UDP-пакетах, имеющих простой формат для запросов, ответов и имен серверов, которые могут быть использованы для продолжения процесса получения ответа. Мы не будем углубляться в детали этого формата. Если в течение некоторого (непродолжительного) времени ответ не приходит, DNS-клиент повторяет запрос и проверяет другой сервер домена после нескольких таких попыток. Этот процесс сконструирован таким образом, чтобы работа не прекращалась, если вышел из строя один из серверов или потерялся один из пакетов. В каждый запрос включен 16-битный идентификатор; он копируется в ответ, и, таким образом, сервер имен может выдавать необходимые ответы на соответствующие им запросы даже в том случае, если в одно и то же время поступает большое количество запросов.

Хотя цель создания DNS проста и понятна, должно быть ясно, что это большая и сложная распределенная система, состоящая из миллионов совместно работающих серверов имен. DNS формирует ключевую связь между удобными для чтения пользователями именами доменов и IP-адресами машин. Она включает дублирование информации и кэширование, направленные на высокую производительность и надежность, и сконструирована таким образом, чтобы быть крайне функциональной.

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

Кроме того, иногда приложениям требуется использовать имена более гибким образом, например назвать контент и обратиться к IP-адресу ближайшего хоста, на котором этот контент есть. Так происходит, в том числе, поиск и скачивание фильмов. В этом случае нас интересует именно фильм, а не компьютер, на котором есть его копия, так что нам нужен только IP-адрес любого ближайшего компьютера, на котором есть искомый ролик. Чтобы достичь такого результата, можно использовать сеть доставки контента (CDN). Как сделать это при помощи DNS, мы опишем позднее, в разделе 7.5.

7.2. Электронная почта

Электронная почта, или как ее часто называют — e-mail, существует уже более трех десятилетий. Она стала популярной с первых дней развития Интернета благодаря скорости и дешевизне. До 1990 года она использовалась преимущественно в научных организациях. В девяностые годы она получила широкую известность, и с тех пор количество отправляемых с помощью электронной почты писем стало расти экспоненциально. Среднее число сообщений, посылаемых ежедневно, скоро во много раз превзошло число писем, отправляемых с помощью обычной почты (snail mail), то есть бумажной. В последнее десятилетие широко распространились и другие формы сетевой коммуникации, такие как обмен мгновенными сообщениями и IP-телефония, но рабочей лошадкой интернет-коммуникации остается электронная почта. Сегодня электронная почта получила широкое применение в промышленности для обмена информацией внутри компаний, что делает возможным совместную работу над сложными проектами далеко удаленных друг от друга сотрудников. К сожалению, так же как и в отношении обычной почты, 9 из 10 сообщений электронной представляют из себя спам (spam) (McAfee, 2010).

Электронной почте, как и любой форме коммуникаций, присущ определенный стиль и набор соглашений. В частности, общение по электронной почте носит очень неформальный и демократичный характер. Скажем, человек, который никогда бы не осмелился позвонить или даже написать бумажное письмо какой-нибудь Особо Важной Персоне (VIP), запросто может сесть и написать ей небрежное электронное сообщение. Часто переписка по e-mail фокусируется на содержании, а не на статусе и устраняет большинство проблем, связанных с различиями в должностном положении, возрасте и поле. Благодаря электронной почте блестящая идея, посланная студентом-практикантом по электронной почте, имеет шанс выиграть у идеи не столь блестящей, но высказанной вице-президентом компании.

В электронной почте люди обожают использовать особый жаргон и сокращения, такие как BTW (By The Way — между прочим), ROTFL (Rolling On The Floor Laughing — Катаюсь по полу от смеха), IMHO (In My Humble Opinion — По моему скромному мнению) и т. д. Кроме того, чрезвычайно популярны так называемые смайлики (smileys), начиная со всем известного «:-)». Если вы его не узнали, поверните книгу на 90° по часовой стрелке. Этот и другие эмотиконы помогают передать тон сообщения. Они заполонили не только переписку по электронной почте, но и обмен мгновенными сообщениями.

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

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

7.2.1. Архитектура и службы

В данном разделе мы рассмотрим возможности и организацию систем электронной почты. Архитектура почтовой системы показана на рис. 7.4. Система электронной почты (система e-mail) состоит из двух подсистем: пользовательских агентов (user agents), позволяющих пользователям читать и отправлять электронную почту, и агентов передачи сообщений (message transfer agents), пересылающих сообщения от отправителя к получателю. Мы будем неформально называть агенты передачи сообщений почтовыми серверами (mail servers).

Рис. 7.4. Архитектура системы e-mail

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

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

Агенты передачи сообщений, как правило, являются системными процессами. Они работают в фоновом режиме на машинах почтовых серверов и всегда должны быть доступными. Они должны автоматически перемещать почтовые сообщения по системе от отправителя получателю при помощи SMTP (Simple Mail Transfer Protocol простого протокола передачи почтовых сообщений). Это шаг, на котором передается сообщение.

SMTP был впервые определен как RFC 821. Далее в него вносились изменения вплоть до текущей редакции RFC 5321. Он отсылает сообщения по соединениям и высылает обратно отчеты о статусе доставки и любых возникших ошибках. Существует множество приложений, в которых подтверждение доставки имеет большую важность и даже может иметь юридическую значимость («Ваша честь, моя электронная система не очень надежна, поэтому я полагаю, что повестка с вызовом в суд просто где-то потерялась»).

Агенты передачи сообщений также используют списки рассылки (mailing lists), которые позволяют доставлять идентичные копии сообщения всем, чьи адреса были включены в список адресов электронной почты. Среди других полезных дополнительных функций можно перечислить следующие: рассылка копий писем «под копирку» (Carbon copy), рассылка копий без уведомления о других получателях (Blind carbon copy), письма с высоким приоритетом, секретная (то есть зашифрованная) почта, возможность доставки письма альтернативному получателю, если основной временно недоступен, а также возможность перепоручать обработку почты секретарям.

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

Рис. 7.5. Конверты и сообщения: а — обычное письмо; б — электронное письмо

Почта пересылается между агентами передачи сообщений в стандартном формате. В первоначально разработанный формат, RFC 822, вносились изменения. Текущая версия носит название RFC 5322; в нее включена поддержка мультимедиа-контента

и международный текст. Данная схема называется MIME, мы поговорим о ней позднее. Хотя многие все еще называют электронную почту RFC 822.

В основе всех современных систем электронной почты лежит ключевая идея о разграничении конверта (envelope) и содержимого письма. Конверт заключает в себе сообщение. Он содержит всю информацию, необходимую для доставки сообщения, — адрес получателя, приоритет, уровень секретности и т. п. Все эти сведения отделены от самого сообщения. Агенты передачи сообщений используют конверт для маршрутизации, аналогично тому, как это делает обычная почтовая служба.

Сообщение внутри конверта состоит из двух отдельных частей: заголовка (header) и тела письма (body). Заголовок содержит управляющую информацию для пользовательских агентов. Тело письма целиком предназначается для человека-получателя. Примеры конвертов и сообщений показаны на рис. 7.5.

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

7.2.2. Пользовательский агент

Пользовательский агент — это программа (иногда называемая почтовым редактором email editor или «читалкой» email reader), управляемая множеством команд для составления и получения сообщений, а также для ответа на сообщения и управления почтовыми ящиками. Существует много популярных пользовательских агентов, например gmail от Google, Microsoft Outlook, Mozilla Thunderbird и Apple Mail. Внешне они сильно отличаются. Графический интерфейс большинства пользовательских агентов основан на меню или значках и требует наличия мышки или, на маленьких мобильных устройствах, возможности управления при помощи касания. Более старые пользовательские агенты, такие как Elm, mh и Pine, имеют интерфейсы, основанные на тексте, и работают при помощи ввода с клавиатуры однобуквенных команд. Функциональных различий нет, по крайней мере, в отношении текстовых сообщений.

Типичные элементы интерфейса пользовательского агента показаны на рис. 7.6. Агент, которым пользуетесь вы, вероятно, выглядит гораздо более современно, но функции, скорее всего, совпадают.

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

На рис. 7.6 показаны семь строк сводной информации. В строках используются поля «От», «Тема» и «Дата получения» в указанном порядке, в которых отображается, от кого получено сообщение, о чем оно и когда было получено. Вся информация отформатирована удобным для пользователя образом; она базируется на полях сообщения, но не отображается буквально. Таким образом, те, кто отправляют сообщения без темы, часто сталкиваются с тем, что их письмам был приписан низкий приоритет.

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

Рис. 7.6. Стандартные элементы интерфейса пользовательского агента.

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

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

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

Распределение по папкам также может автоматически проводить пользовательский агент до того, как пользователь прочтет сообщение. Примером этого служит проверка полей и содержания сообщения, а также отзывов пользователя о предыдущих сообщениях, предназначенные для определения того, является ли письмо спамом. Многие интернет-провайдеры и компании используют программное обеспечение, помечающее сообщения как важные или спам, так что пользовательский агент может распределить их по соответствующим папкам. У интернет-провайдеров и компаний есть преимущество работы с множеством сообщений, так что у них могут быть списки известных спамеров. Если сотни пользователей в одно и то же время получают одинаковые сообщения, они, вероятно, являются спамом. Предварительно сортируя сообщения и помечая часть из них как «предположительно спам», пользовательский агент может избавить пользователей от массы работы по разделению нужного и ненужного.

Но какой же спам является наиболее популярным? Он генерируется набором взломанных компьютеров, которые называются ботнет (botnet, «ботсеть»), а его содержание зависит от страны, в которой вы живете. В Азии самыми популярными являются предложения поддельных дипломов, в США — дешевых лекарств и сомнительной продукции. Невостребованные счета в нигерийском банке также не теряют популярности. Ну, а таблетки для увеличения определенных частей тела входят в топ-лист, где бы вы не жили.

Кроме того, сами пользователи могут придумывать правила распределения писем по папкам. Каждое правило определяет состояние и действие. Например, правило может гласить, что письмо, полученное от начальника, должно перемещаться в папку для немедленного прочтения, а письма от определенного списка отправителей должны помещаться в другую папку для того, чтобы их можно было прочитать позднее. На рис. 7.6 изображено несколько папок. Самые важные из них — это Inbox (Входящие), для входящей почты, которая не была никуда перемещена при получении, и Spam (Спам), для сообщений похожих на спам.

Помимо распределения почтовых сообщений по папкам пользовательские агенты предоставляют широкие возможности поиска писем в почтовом ящике. Эта опция также показана на рис. 7.6. Возможность поиска позволяет пользователям быстро находить сообщения. Например, можно найти сообщение, содержавшее строку «where to buy Vegemite», которое было получено в прошлом месяце.

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

Еще одна полезная опция — это способность определенным образом автоматически отвечать на сообщения. Один из вариантов ответа — пересылка входящего сообщения на другой адрес, например на компьютер, принадлежащий коммерческой пейджинговой компании, чтобы вызвать пользователя, используя радио или спутниковую антенну, и отобразить строку «Тема» на его пейджере. Эти автоответчики (autoresponders) должны работать на почтовых серверах, так как пользовательский агент может работать не все время, а также может только иногда извлекать почту. Из-за этих факторов пользовательский агент не обеспечивает настоящего автоматического ответа. Однако интерфейс для автоматических ответов обычно предоставляется пользовательским агентом.

Еще один пример автоматического ответа — агент на отпуск (vacation agent). Это программа, которая просматривает каждое входящее сообщение и посылает отправителю нейтральный ответ, например: «Привет, я в отпуске. Вернусь 24-го августа. Тогда с тобой и свяжусь». В подобных ответах также может быть сказано, каким образом действовать в экстренной ситуации, если она возникнет во время отсутствия адресата, к каким людям стоит обращаться по вопросам определенных проблем и т. д. Большинство агентов на отпуск ведут запись того, кому были отосланы автоматические ответы, и избавляют от необходимости повторно отвечать данному человеку. Однако и с этими агентами есть определенные трудности. Например, нежелательно отсылать заготовленный ответ большому списку адресатов.

Теперь давайте обратимся к сценарию отсылки сообщения одним пользователем другому. Одна из основных не обсужденных нами функций, которую поддерживают пользовательские агенты, — это написание сообщения. Данный процесс включает создание сообщений, ответы на них и отсылку этой почты остальной части почтовой системы с целью их доставки. Хотя для создания тела сообщения может быть использован любой текстовый редактор, обычно редакторы интегрируются в пользовательские агенты. Это позволяет проще добавлять адресатов и прописывать темы и другую информацию в нужные поля. Например, при ответе на сообщение почтовая система может извлечь адрес отправителя из входящего сообщения и автоматически подставить его на нужное место в ответе. Другие часто встречающиеся возможности — это добавление блока с подписью (signature block) в конец сообщения, исправление ошибок, вычисление цифровых подписей, подтверждающих истинность сообщения.

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

Ожидаемый формат адреса — это user@dns-address. Так как система доменных имен DNS уже рассматривалась выше в этой главе, сейчас мы не станем подробно останавливаться на данном вопросе. Однако следует отметить, что существуют и другие формы адресации. В частности, адреса стандарта X.400 абсолютно не похожи на DNS-адреса.

X.400 — это стандарт ISO для систем обработки сообщений, который одно время соревновался с SMTP. SMTP победил в этом противостоянии, хотя системы X.400 все еще используются (в основном, за пределами США). Адреса стандарта X.400 абсолютно не похожи на DNS-адреса и состоят из пар атрибут = значение, разделенных слэшами, например:

В этом адресе указано государство, штат, местоположение, личный адрес и имя получателя (Ken Smith). Возможно также использование различных других атрибутов, что делает возможным отправку электронного письма человеку, чьего имени вы не знаете, при условии что вам известны другие атрибуты (например, название компании и должность получателя). Хотя форма адресации X.400 значительно менее удобна, чем DNS, для пользовательских агентов этот вопрос является спорным, так как они поддерживают удобные с точки зрения пользователя псевдонимы (aliases,

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

Последний вопрос, который мы обсудим в рамках разговора об отсылке почты, — это списки рассылки, позволяющие пользователю рассылать одно и то же сообщение группе получателей при помощи одной команды. Есть два варианта того, как может храниться список рассылки. Первый — локальное хранение пользовательским агентом. В этом случае пользовательский агент может просто послать каждому получателю отдельное сообщение. Помимо этого список может храниться удаленно на агенте передачи сообщений. Тогда сообщения будут тиражироваться в системе передачи сообщений, что позволяет множеству пользователей отсылать письма данному списку. Допустим, у группы исследователей птиц есть список рассылки, называющийся birders (птицеловы), установленный на агенте передачи сообщений meadowlark.arizona.edu. Тогда любое сообщение, посланное по адресу [email protected], будет сначала отправляться в университет штата Аризона, а затем рассылаться оттуда в виде отдельных сообщений всем членам списка рассылки, где бы они ни находились. Для отправителя письма список рассылки внешне не отличается от обычного индивидуального адреса. Если отправитель не знает, что birders — это список рассылки, он вполне может подумать, что посылает письмо лично некоему профессору по имени Gabriel O. Birders.

7.2.3. Форматы сообщений

Перейдем теперь от рассмотрения пользовательского интерфейса к формату самих сообщений электронной почты. Чтобы сообщения, отсылаемые пользовательским агентом, обрабатывались агентами передачи сообщений, они должны быть оформлены в соответствии с определенными стандартами. Сначала мы рассмотрим основной ASCII-формат электронного письма стандарта RFC 5322, который является последним вариантом оригинального формата интернет-сообщений, описанного в RFC 822. Затем мы познакомимся с мультимедийным расширением этого первоначального стандарта.

RFC 5322 — формат интернет-сообщений

Сообщения состоят из примитивного конверта (описанного как часть SMTP в RFC 5321), нескольких полей заголовка, пустой строки и, наконец, тела сообщения. Каждое поле заголовка (логически) состоит из одной строки ASCII-текста, содержащей имя поля, двоеточие и (в большинстве случаев) значение поля. Первоначальный RFC 822 был создан несколько десятилетий назад и в нем нет четкого разграничения конверта и заголовка. Хотя частично стандарт был пересмотрен в RFC 5322, целиком обновить его было невозможно, поскольку RFC 822 уже был очень широко распространен. Обычно пользовательский агент формирует сообщение и передает его агенту передачи сообщений, который с помощью одного из полей заголовка создает конверт нового вида, представляющий собой некую старомодную смесь сообщения и конверта.

Основные поля заголовка, связанные с транспортировкой сообщения, перечислены в табл. 7.3. Поле To: содержит DNS-адрес основного получателя. Возможно наличие и нескольких получателей. В поле Cc: указываются адреса дополнительных получателей. С точки зрения доставки, никакой разницы между основным и дополнительными получателями нет. Разница между ними чисто психологическая и, может быть, важна для людей, но совершенно не существует для почтовой системы. Термин Cc: (carbon copy — экземпляр, сделанный «под копирку») несколько устарел, так как при работе с компьютерами копировальная бумага вообще-то не используется, тем не менее он прочно обосновался в электронной почте. Поле Bcc: (Blind carbon copy — слепая копия) аналогично предыдущему, с той разницей, что в последнем случае строка этого поля удаляется из всех экземпляров сообщения, отправленных как основному, так и дополнительным получателям. Это свойство позволяет рассылать одно письмо одновременно нескольким получателям так, что получатели не будут знать, что это письмо послано еще кому-либо кроме них.

Таблица 7.3. Поля заголовка стандарта RFC 5322, связанные с транспортировкой сообщения

Следующие два поля, From: и Sender:, сообщают соответственно, кто составил и отправил сообщение. Это могут быть разные люди. Например, написать письмо может руководитель предприятия, а отослать — его секретарь. В этом случае руководитель будет числиться в поле From:, а секретарь — в поле Sender:. Поле From: является обязательным, тогда как поле Sender: может быть опущено, если его содержимое не отличается от содержимого поля From:. Эти поля нужны на случай, если сообщение доставить невозможно и об этом следует проинформировать отправителя. Кроме того, по адресам, указанным в этих полях, может быть оправлен ответ.

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

Поле Return-Path: добавляется последним агентом передачи сообщений. Предполагалось, что это поле будет сообщать, как добраться до отправителя. Теоретически, эта информация может быть собрана из всех полей Received: заголовка (кроме имени почтового ящика отправителя), однако на практике оно редко заполняется подобным образом и обычно просто содержит адрес отправителя.

Помимо полей, показанных в табл. 7.3, сообщения стандарта RFC 5322 могут также содержать широкий спектр полей заголовка, используемых пользовательским агентом или самим пользователем. Наиболее часто используемые поля заголовка приведены в табл. 7.4. Информации в таблице достаточно, чтобы понять назначение полей, поэтому мы не станем рассматривать их все подробно.

Таблица 7.4. Некоторые поля, используемые в заголовке сообщения стандарта RFC 5322

Поле Reply-to: иногда используется в случае, если ни составитель письма, ни его отправитель не хотят получать на него ответ. Например, управляющий отделом сбыта может написать письмо, информирующее клиентов о новом продукте. Это письмо отправляется его секретарем, но в поле Reply-to: указан адрес менеджера отдела продаж, который может ответить на вопросы и принять заказы. Это поле также может быть полезным, если у отправителя есть два адреса электронной почты и он хочет, чтобы ответы приходили не на тот, с которого он отправляет сообщение.

Message-Id: — это автоматически генерируемое число, которое используется, чтобы связывать сообщения (например, при ответе на письмо) и избежать повторной доставки.

В документе RFC 5322 открыто сказано, что пользователям разрешается изобретать дополнительные заголовки для своих нужд. Начиная с формата RFC 822, заголовки начинаются со строки X-. Гарантируется, что в будущем никакие стандартные заголовки не будут начинаться с этих символов, чтобы избежать конфликтов между официальными и частными заголовками. Иногда умники-студенты включают поля вроде X-Fruit-of-the-Day: (сегодняшний плод) или X-Disease-of-the-Week: (недуг недели), использование которых вполне законно, хотя их смысл и не всегда понятен.

После заголовков идет тело самого сообщения. Пользователь может разместить в нем все, что ему угодно. Некоторые люди завершают свои послания сложными подписями, включающими популярные и малоизвестные цитаты, политическими заявлениями и разнообразными объявлениями (например, «Корпорация АБВ не несет ответственности за высказанное выше мнение. Собственно, она даже не в силах постичь его»).

MIME — многоцелевые расширения электронной почты в сети Интернет

На заре существования сети ARPANET электронная почта состояла исключительно из текстовых сообщений, написанных на английском языке и представленных символами ASCII. Для подобного использования первоначального стандарта RFC 822 было вполне достаточно: он определял формат заголовков, но оставлял содержимое сообщения полностью на усмотрение пользователей. В 1990-е годы всемирное использование Интернета и необходимость посылать более разнообразный контент через почтовую систему показали, что такой подход уже не удовлетворяет пользователей, привыкших к Интернету. Требовалось обеспечить возможность отправления сообщений на языках с надстрочными знаками (например, на французском и немецком), на языках, использующих алфавиты, отличные от латинского (например, на иврите или русском), или на языках без алфавитов (например, китайском и японском). Также требовалась возможность отсылки сообщений, не являющихся текстом (например, аудио, изображения или бинарные документы и программы).

Решением стала разработка MIME (Multipurpose Internet Mail Extensions — многоцелевые расширения электронной почты в Интернете). Они широко применяются как для почтовых сообщений, посылаемых через Интернет, так и для описания контента в других приложениях, таких как веб-сайты. MIME описаны в RFC 2045-2047, 4288, 4289 и 2049.

Основная идея стандартов MIME — продолжить использование формата RFC 822 (предшественника формата RFC 5322, действовавшего в то время, когда были предложены MIME), но с добавлением структуры к телу сообщения и с определением правил кодировки для передачи не-ASCП-сообщений. Не отклоняясь от стандарта RFC 822, MIME-сообщения могут передаваться с помощью обычных агентов передачи сообщений и протоколов (ранее основанных на RFC 821, а сейчас на RFC 5321). Все, что нужно было изменить, — это отправляющие и принимающие программы, которые пользователи могли создать для себя сами.

Стандартами MIME определяются пять новых заголовков сообщения, приведенных в табл. 7.5. Первый заголовок (MIME-Version:) просто информирует пользовательского агента, получающего сообщение, что тот имеет дело с сообщением MIME, а также сообщает ему номер версии MIME, используемой в этом сообщении. Если сообщение не содержит такого заголовка, то оно считается написанным на английском языке (или, по крайней мере, на языке, использующем только знаки ASCII) и обрабатывается соответствующим образом.

Таблица 7.5. Заголовки сообщений, добавленные MIME

Заголовок Content-Description: представляет собой ASCII-строку, информирующую о том, что находится в сообщении. Этот заголовок позволяет пользователю принять решение о том, нужно ли ему декодировать и читать сообщение. Если в строке сказано: «Фотография тушканчика Барбары», а получивший это сообщение не является любителем тушканчиков, то, вероятнее всего, он сразу удалит это сообщение, а не станет перекодировать его в цветную фотографию высокого разрешения.

Заголовок Content-Id: содержит идентификатор содержимого сообщения. В нем используется тот же формат, что и в стандартном заголовке Message-Id:.

Заголовок Content-Transfer-Encoding: сообщает о способе упаковки тела сообщения для его передачи по сети. Во времена разработки MIME основной проблемой были протоколы передачи сообщений (SMTP), предполагавшие, что сообщение будет в формате ASCII, при этом в строке должно было быть не более 1000 символов. Символы ASCII используют 7 бит из каждого восьмибитного байта. Бинарные данные, такие как исполняемые программы и изображения, используют все 8 бит байта, так же как и расширенные наборы символов. Не было никакой гарантии того, что эти данные будут передаваться безопасно. В результате этого потребовался метод передачи бинарных данных, который заставлял бы их выглядеть как обычное почтовое сообщение ASCII. Расширения SMTP, введенные с момента разработки MIME, на самом деле позволяют передавать восьмибитные бинарные данные, хотя даже сегодня незакодированные бинарные данные не всегда корректно передаются почтовой системой.

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

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

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

Кодировка бинарных данных в формате ASCII называется base64 (64-символьная кодировка). При использовании данного метода группы по 24 бита разбиваются на четыре единицы по 6 бит, каждая из которых посылается в виде обычного разрешенного ASCII-символа. В этой кодировке 6-разрядный символ 0 кодируется ASCII-символом «A», 1 — ASCII-символом «В» и т. д. Затем следуют 26 строчных букв, затем 10 цифр и, наконец, + и / для кодирования 62 и 63 соответственно. Последовательности == и = говорят о том, что последняя группа содержит только 8 или 16 бит соответственно. Символы перевода строки и возврата каретки игнорируются, поэтому их можно вставлять в любом месте закодированного потока символов для того, чтобы строки

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

Для сообщений, почти полностью состоящих из символов ASCII, но с небольшими включениями не-ASCП-символов, подобный метод несколько неэффективен. Вместо него лучше применять кодировку quoted-printable (цитируемое печатное кодирование). Это просто 7-битный ASCII, в котором символы, соответствующие значениям ASCII-кода свыше 127, кодируются знаком равенства, за которым следуют две шестнадцатеричных цифры — ASCII-код символа. Кроме конечных пробелов кодируются также символы управления, некоторые пунктуационные знаки и математические символы.

Наконец, когда имеются веские причины не использовать эти методы, можно указать в заголовке Content-Transfer-Encoding: свою кодировку.

Последний заголовок в табл. 7.5 представляет наибольший интерес. Он указывает тип тела сообщения и его применение выходит далеко за пределы электронной почты. Например, контент, загружаемый из Интернета, помечается символами MIME, что позволяет браузеру адекватно отображать информацию. Так обстоит дело с контентом, пересылаемым через потоковое мультимедиа, и передачей в реальном времени, например голоса через IP (VoIP).

Изначально в документе RFC 1521 были определены семь типов содержимого сообщений, каждый из которых распадается на несколько доступных подтипов. Подтип отделяется от типа косой чертой, например «Content-Type: video/mpeg». С тех пор к ним было добавлено много новых типов и подтипов. Этот список пополняется всякий раз при возникновении соответствующей необходимости. В сети его поддерживает IANA, он доступен по адресу www.iana.org/assignments/media-types.

Типы и примеры часто используемых подтипов приведены в табл. 7.6. Давайте кратко остановимся на каждом из них, начиная с типа text. Комбинация text/plain служит для обозначения обычного текстового сообщения, которое может быть отображено на экране компьютера сразу после получения. Для этого не требуется дополнительной обработки или перекодировки. Это значение поля заголовка позволяет передавать обычные сообщения в MIME с добавлением небольшого количества дополнительных заголовков. Когда веб-технологии стали популярны, был добавлен новый тип text/html (в RFC 2854), который позволил пересылать веб-страницы в теле письма RFC 822. В RFC 3023 определен подтип для расширяемого языка разметки (extensible Markup Language — XML), text/xml. С развитием Интернета количество документов XML стремительно увеличилось. Ниже, в разделе 7.3, мы рассмотрим HTML и XML.

Следующим типом MIME является image. Он используется для передачи неподвижных изображений. На сегодняшний день существует множество различных форматов хранения и передачи изображений, как с использованием сжатия, так и без него. Некоторые форматы, в том числе GIF, JPEG и TIFF, встроены практически во все браузеры, однако существует еще множество других типов и соответствующих им подтипов.

Типы audio и video предназначены, соответственно, для передачи звука и двигающегося изображения. Обратите внимание на то, что подтип video включает только визуальную информацию, а не звуковую дорожку. Если необходимо передать по электронной почте видеофильм со звуком, то, возможно, придется посылать видеоряд и звуковую дорожку отдельно друг от друга. Это зависит от системы кодирования. Первым видеоформатом, который был определен стандартом MIME, стал формат со скромным названием MPEG (Motion Pictures Experts Group — экспертная группа по вопросам движущегося изображения). С тех пор было добавлено еще несколько форматов. Так, чтобы позволить пользователям пересылать по электронной почте аудиофайлы в формате MP3, в RFC 3003 помимо уже существующего audio/basic был добавлен тип audio/mpeg. Типы video/mp4 и audio/mp4 указывают на видео- и аудиоданные в новом формате MPEG 4.

Таблица 7.6. Типы стандарта MIME и примеры подтипов

Тип

Подтип

Описание

text

plain, html, xml, css

Текст в различных форматах

image

gif, jpeg, tiff

Изображения

audio

basic, mpeg, mp4

Звуки

video

mpeg, mp4, quicktime

Видеофильмы

model

vrml

3D-модель

application

onoctet-stream, pdf, javascript, zip

Данные, производимые приложениями

message

http, rfc822

Инкапсулированное сообщение

multipart

mixed, alternative, parallel, digest

Комбинация нескольких типов

Тип model был добавлен позднее, чем остальные типы контента. Он предназначен для описания 3D-моделей. Однако пока он не особо широко используется.

Тип application (приложение) предназначен для всех форматов, которые не покрываются остальными типами и требуют от приложения интерпретации данных. Мы перечислили подтипы pdf, javascript и zip как примеры PDF-документов, программ на Java-Script и архивов в формате Zip соответственно. Пользовательские агенты, получающие этот контент, используют для его отображения стороннюю библиотеку или внешнюю программу. Отображение может быть интегрировано в пользовательский агент, а может и не быть.

Используя типы MIME, пользовательские агенты расширяют возможности обработки новых типов контента по мере их появления. Это значительное преимущество. С другой стороны, многие новые формы контента обрабатываются и интерпретируются приложениями, что представляет некоторую опасность. Совершенно очевидно, что запуск произвольной исполняемой программы, которая пришла по электронной почте от «друга», влечет за собой определенный риск. Такая программа может серьезно повредить те части компьютера, к которым получает доступ, особенно если она может считывать и создавать файлы и использовать сеть. Форматы документов также могут нести определенную угрозу, хотя это менее очевидно. Подобную возможность нельзя исключать, так как форматы типа PDF являются замаскированными развитыми языками программирования. Несмотря на то что они интерпретируются и ограничены в доступной им области, ошибки в интерпретаторе часто позволяют документам избежать ограничений обходными путями.

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

Последние два типа, о которых пойдет речь, полезны при создании сообщений и манипулировании ими. Тип message позволяет помещать одно сообщение в другое. Это может быть полезно для переадресации письма. Если внутри одного сообщения заключено целое сообщение стандарта RFC 822, следует использовать подтип rfc822. Сходным образом обычно инкапсулируются документы в формате HTML. А подтип partial позволяет разбивать сообщение на части и передавать их отдельно (например, в случае, когда инкапсулированное сообщение является слишком длинным). Параметры обеспечивают восстановление сообщения получателем из отдельных фрагментов в правильном порядке.

Наконец, тип multipart позволяет составлять сообщение из нескольких частей, при этом начало и конец каждой части отчетливо указывается. Подтип mixed позволяет создавать сообщение из частей различных форматов. Многие почтовые программы позволяют пользователю прикрепить к текстовому сообщению одно или более приложений. Эти приложения пересылаются с использованием типа multipart. В случае применения подтипа alternative, напротив, каждая часть должна содержать одно и то же сообщение, но в другом виде или другой кодировке. Например, сообщение может быть послано в виде простого ASCII-текста, а также в форматах HTML и PDF. Грамотно созданный пользовательский агент, получив такое сообщение, сначала попытается отобразить его в формате, зависящем от предпочтений пользователя. Скорее всего, это будет PDF, если данный формат допустим. Если это по какой-либо причине невозможно, тогда производится попытка отобразить часть в формате HTML. Если и это невозможно, отображается ASCII-текст. Части следует располагать в порядке увеличения сложности, чтобы даже старые (до MIME) пользовательские агенты смогли отобразить сообщение, хотя бы в виде простого ASCII-текста.

Подтип alternative также может использоваться для сообщений, посылаемых одновременно на разных языках. В этом контексте знаменитый розеттский камень, найденный в Египте, может считаться одним из ранних вариантов сообщений типа multipart/alternative.

Что касается двух других примеров подтипов, подтип parallel используется, когда все части должны «просматриваться» одновременно. Например, в фильмах часто есть видео- и аудиодорожки. Гораздо приятнее смотреть фильм, если эти две дорожки проигрываются одновременно, а не последовательно. Подтип digest используется, когда несколько сообщений объединяются в одно составное. Например, какая-нибудь дис

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

Пример того, как типы MIME могут использоваться для сообщений электронной почты, приведен в листинге 7.2. В данном случае поздравление с днем рождения посылается одновременно в двух альтернативных формах: в виде HTML и в виде аудиозаписи. Если у получателя есть возможность воспроизвести звуковой файл, пользовательский агент воспроизведет его. В этом примере звук передается как подтип message/external-body по ссылке, так что сначала пользовательский агент должен обратиться за звуком к файлу birthday.snd через FTP. В противном случае на экране получателя в полной тишине отобразится текст сообщения. Эти две части письма разделены двойными дефисами, за которыми следует (определяемая пользователем) строка, указанная как значение параметра boundary (граница).

Листинг 7.2. Сообщение типа multipart, содержащее HTML и аудио

Обратите внимание: заголовок Content-Type трижды встречается в данном сообщении. На верхнем уровне он указывает, что сообщение состоит из нескольких частей. Для каждой части он сообщает ее тип и подтип. Наконец, в теле второй части сообщения он указывает пользовательскому агенту тип внешнего файла. Чтобы подчеркнуть это различие, мы использовали в последнем случае строчные символы, хотя для всех заголовков регистр символа не имеет значения. Для внешнего тела в формате, отличном от 7-разрядного ASCII, также требуется заголовок content-transfer-encoding.

7.2.4. Пересылка сообщений

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

Для этого проще всего установить транспортное соединение от машины-источника до машины-приемника, а затем просто передать по нему сообщение. Так изначально работал SMTP. Однако за последние годы возникло два разных способа использования SMTP. Первый — для подачи почтового сообщения (mail submission, первый шаг в архитектуре e-mail на рис. 7.4). Этим способом пользовательские агенты переправляют сообщения в почтовую систему для их дальнейшей отправки. Второй вариант использования — передача сообщений между агентами передачи сообщений (шаг 2 на рис. 7.4).

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

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

SMTP — простой протокол электронной почты и его расширения

В Интернете для доставки электронной почты машина-источник устанавливает TCP-соединение с портом 25 машины-приемника. Этот порт прослушивается почтовым демоном и их общение происходит с помощью протокола SMTP (Simple Mail Transfer Protocol простой протокол передачи электронной почты). Этот сервер принимает входящие соединения, проверяет их безопасность и принимает сообщения для доставки. Если письмо невозможно доставить, отправителю возвращается сообщение об ошибке, содержащее первую часть этого письма.

Протокол SMTP представляет собой простой ASCII-протокол. Это не недостаток, а отличительная черта. Использование текста в формате ASCII позволяет легко модифицировать, тестировать и исправлять ошибки в протоколах. Они могут тестироваться отсылкой команд вручную, при этом записи сообщений легко читать. Сейчас так работает большинство интернет-протоколов прикладного уровня (например, HTTP).

Мы поговорим о простой передаче сообщений между почтовыми серверами, их доставляющими. Установив TCP-соединение с портом 25, передающая машина, выступающая в роли клиента, ждет запроса принимающей машины, работающей в режиме сервера. Сервер начинает диалог с того, что посылает текстовую строку, содержащую его идентификатор и сообщающую о его готовности (или неготовности) к приему почты. Если сервер не готов, клиент разрывает соединение и повторяет попытку позднее.

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

протокол TCP обеспечивает надежный байтовый поток. Если у отправителя есть еще почта, она также отправляется. После передачи всей почты в обоих направлениях соединение разрывается. Пример диалога клиента и сервера при передаче сообщения из листинга 7.2 показан в листинге 7.3. Строки, посланные клиентом (то есть отправителем), помечены буквой C:, а посланные сервером (то есть получателем) — S:.

Сначала клиент, естественно, посылает приветствие серверу. Таким образом, первая команда клиента выглядит как HELO, что представляет собой наиболее удачный из двух вариантов сокращения слова HELLO до четырех символов. Зачем все эти команды было нужно сокращать до четырех букв, сейчас уже никто не помнит.

В нашем примере сообщение должно быть послано только одному получателю, поэтому используется только одна команда RCPT (сокращение от слова recipient — получатель). Использование этой команды несколько раз позволяет посылать одно сообщение нескольким получателям. Каждое из них подтверждается или отвергается индивидуально. Несмотря на то что попытки пересылки сообщения некоторым получателям оказываются неудачными (например, из-за отсутствия адресатов), это сообщение все равно может быть доставлено остальным адресатам, числящимся в списке рассылки.

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

Базовый протокол SMTP работает хорошо, но он ограничен в некоторых отношениях. Он не включает аутентификацию. Это значит, что команда FROM в примере может выдать любой адрес отправителя, который ей понравится. Это крайне удобно для отсылки спама. Другое ограничение заключается в том, что SMTP передает сообщения ASCII, а не бинарные данные. Именно для этого была нужна кодировка base64 для передачи контента MIME. Однако с этой кодировкой при передаче почты недостаточно используется пропускная способность, что неприятно, если отправляется объемное сообщение. Третье ограничение заключается в том, что SMTP отсылает непосредственно сообщение. Оно не шифруется и никак не защищено.

Чтобы справиться с этими и многими другими проблемами, связанными с передачей сообщений, к SMTP было добавлено расширение. Оно является обязательной частью стандарта RFC 5321. Использование SMTP с расширениями называется ESMTP (Extended SMTP — расширенный SMTP).

Листинг 7.3. Передача сообщения от [email protected] для [email protected]

Клиенты, желающие использовать расширенную версию, в начале высылают EHLO вместо HELO. Если этот вариант отвергается, сервер работает с обычным SMTP, а пользователь должен идти по стандартному пути. Если EHLO принимается, сервер отвечает, какие расширения он поддерживает. После этого клиент может использовать любое из перечисленных расширений. Несколько стандартных расширений показаны в табл. 7.7. В ней даны ключевые слова, в том виде, в котором они используются в механизме расширения, и описание новой функциональности. Более подробно рассматривать расширения мы не будем.

Таблица 7.7. Некоторые расширения SMTP

Чтобы лучше понять, как работает SMTP и другие рассмотренные в этой главе протоколы, попробуйте сами поработать с ними. В любом случае, для начала найдите машину, подключенную к Интернету. В системе UNIX (или Linux) наберите в командной строке: telnet mail.isp.com 25

подставив вместо mail.isp.com DNS-имя почтового сервера провайдера. В системе Windows XP щелкните на кнопке Пуск, затем на кнопке Выполнить и наберите команду в диалоговом окне. На компьютерах с Vista или Windows 7 вам, возможно, сначала придется инсталлировать программу telnet (или ее эквивалент) и запустить ее. В результате выполнения этой команды будет установлено telnet-соединение (то есть соединение TCP) с портом 25 данной машины. Как было показано в табл. 6.4, порт 25 является SMTP-портом (см. табл. 6.4 с портами для других стандартных протоколов). В ответ на введенную команду вы получите что-то вроде этого:

Trying 192.30.200.66™

Connected to mail.isp.com Escape character is ‘Л]'.

220 mail.isp.com Smail #74 ready at Thu, 25 Sept 2002 13:26 +0200

Первые три строки посылаются telnet и поясняют для вас происходящее. Последняя строка посылается сервером SMTP удаленной машины и сообщает о готовности к общению с вашей машиной и приему почты. Чтобы узнать о доступных командах, наберите HELP

Начиная с этого момента, возможен обмен последовательностями команд, показанными в листинге 7.3, если сервер готов принимать от вас почтовые сообщения.

Подача почтовых сообщений

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

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

Эта удаленная коммуникация не вызывает проблемы сама по себе. Именно для подобных случаев был разработан протокол TCP/IP. Однако провайдер или компания обычно без энтузиазма относятся к тому, что у удаленного пользователя будет возможность подавать сообщения на их почтовый сервер для доставки в какое-то иное место. Такой сервер не является общественным. Кроме того, этот вид открытой почтовой станции (open mail relay) привлекает спамеров. Это происходит из-за наличия возможности скрыть настоящего отправителя и таким образом затруднить идентификацию сообщения как спама.

Учитывая эти особенности, SMTP обычно используется для подачи писем с расширением AUTH. Это расширение позволяет серверу проверять данные отправителя (имя пользователя и пароль) для подтверждения того, что сервер должен обеспечить работу с почтой.

Есть еще несколько отличий в том, как SMTP используется при подаче почты. Например, задействуется порт 587, а не порт 25, и SMTP-сервер может проверять и исправлять формат сообщений, отосланных пользовательским агентом. Чтобы узнать больше об использовании SMTP при подаче писем, посмотрите RFC 4409.

Передача сообщений

Когда отсылающий агент передачи почты (сообщений) получает сообщение от пользовательского агента, он доставляет его получающему агенту передачи почты, используя SMTP. Чтобы это сделать, отсылающая сторона использует адрес назначения. Посмотрите на сообщение в листинге. 7.2, адресованное к [email protected]. На какой почтовый сервер оно должно быть доставлено?

Чтобы определить верный почтовый сервер, запрашивается DNS. В предыдущем разделе мы описали то, как в состав DNS входят различные типы записей, включающие запись MX (mail exchanger — запись для обмена почтовыми сообщениями). В этом случае запрос DNS делается для записей MX домена ee.uwa.edu.au. Этот запрос возвращает упорядоченный список имен и IP-адресов одного или более почтовых серверов.

Затем отсылающий агент передачи почты создает TCP-соединение с IP-адресом почтового сервера на порте 25, чтобы связаться с принимающим агентом передачи почты. Для передачи сообщения используется SMTP. Принимающий агент передачи почты затем помещает сообщения для пользователя bob в нужный почтовый ящик, чтобы позднее Боб мог их прочитать. Этот шаг локальной доставки может включать перемещение сообщения между компьютерами, если существует разветвленная почтовая инфраструктура.

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

Еще один пример перенаправления почты выглядит следующим образом: Боб мог закончить Массачусетский технологический институт и, соответственно, быть доступным по адресу [email protected]. Вместо того чтобы собирать почту с разных аккаунтов, Боб может сделать так, чтобы почта, посылаемая на данный адрес, переправлялась на [email protected]. В этом случае сообщения, отправленные на bob@alum.

mit.edu, будут доставляться дважды. Сначала они будут посылаться на почтовый сервер alum.mit.edu. Затем на сервер ee.uwa.edu.au. Каждый из этих шагов является полноценной отдельной доставкой, если мы рассматриваем их с точки зрения агентов передачи почтовых сообщений.

Также не стоит забывать о спаме. Сегодня девять из десяти отсылаемых сообщений принадлежат именно к этой категории (McAfee, 2010). Мало кто хочет получать подобную почту, но ее сложно избежать, так как нежелательные сообщения маскируются под обычные. До приема сообщения могут быть проведены дополнительные проверки, чтобы сократить возможности спама. Сообщение для Боба было отослано с адреса [email protected]. Принимающий агент передачи почты может обратиться к агенту передачи почты, отправившему сообщение, через DNS. Это позволяет проверить, совпадает ли IP-адрес на другом конце TCP-соединения и DNS-имя. В общем случае, получающий агент может проверить отсылающий домен в DNS и выяснить, придерживается ли он политики отправки почты. Эта информация часто выдается в формате TXT- и SPF-записей. В ней может говориться о том, что возможно проведение и других проверок. Например, почта, посылаемая с cs.washington.edu, может всегда отправляться с хостаjune.cs.washington.edu. Если высылающий агент передачи почты не june, возникает проблема.

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

7.2.5. Окончательная доставка сообщений

Наше почтовое сообщение почти доставлено. Оно прибыло в почтовый ящик Боба. Осталось только передать копию сообщения пользовательскому агенту Боба, чтобы оно могло отобразиться. Это шаг 3 в архитектуре на рис. 7.4. Когда пользовательский агент и агент передачи почты работали на одном и том же компьютере и представляли собой всего лишь разные процессы, эта задача была несложной. Агент передачи почты просто писал новые сообщения в конце файла почтового ящика, а пользовательский агент просто проверял файл почтового ящика на наличие новых сообщений.

Сегодня пользовательский агент, работающий на персональном компьютере, ноутбуке или мобильном телефоне, вероятно, будет размещаться не на почтовом сервере компании или провайдера. Пользователи хотят иметь доступ к своей почте вне зависимости от того, где они находятся. Им нужен доступ к почте на работе, с домашнего компьютера, с ноутбука в командировках или из интернет-кафе, когда они отдыхают. Им нужна возможность работать без постоянного соединения с сетью, периодически подключаясь к Интернету для получения входящих сообщений и отправки исходящих. Более того, каждый пользователь может запускать несколько агентов в зависимости от того, каким компьютером ему удобнее пользоваться в данный момент. Несколько пользовательских агентов даже могут работать одновременно.

В данном случае пользовательский агент должен отображать содержимое почтового ящика и позволять работать с ним удаленно. Для этой цели может задействоваться несколько разных протоколов, но только не SMTP. SMTP — это протокол, основанный на проталкивании данных. Для передачи сообщения ему необходимо соединение с удаленным сервером. Таким образом, окончательная доставка не может быть осуществлена по двум причинам: из-за того, что почтовый ящик должен храниться на агенте передачи почты, и из-за того, что пользовательский агент может быть не подключен к Интернету, когда SMTP пытается передать сообщение.

IMAP — протокол доступа к электронной почте в Интернете

Один из главных протоколов, использующихся для конечной доставки, — это IMAP (Internet Mail Access Protocol протокол доступа к электронной почте в Интернете). Четвертая версия этого протокола определена в RFC 3501. Чтобы использовать IMAP, почтовый сервер запускает IMAP-сервер, который проверяет порт 143. Пользовательский агент запускает IMAP-клиент. Этот клиент соединяется с сервером и начинает передавать команды из перечисленных в табл. 7.8.

Сначала клиент запускает защищенный транспорт, если он используется (чтобы сохранить конфиденциальность сообщений и команд), а затем вводит логин и пароль или иначе авторизуется на сервере. После входа в систему можно воспользоваться множеством команд, чтобы просматривать папки и сообщения или даже части сообщений, помечать письма галочками для дальнейшего удаления и разбирать их по папкам. Обратите внимание на то, что во избежание неразберихи мы в этой главе используем слово «папка» (folder), основываясь на том, что почтовый ящик пользователя состоит из нескольких таких папок. Однако в спецификации IMAP вместо папки используется термин mailbox («почтовый ящик»). Таким образом, получается, что у пользователя есть много почтовых ящиков IMAP, каждый из которых пользователь видит как папку.

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

IMAP — это улучшенная версия ранее разработанного протокола окончательной доставки POP3 (Post Office Protocol, version 3 протокол почтового отделенияверсия 3), который определен в RFC 1939. Протокол POP3 проще, но он поддерживает меньше возможностей и является менее безопасным при обычном использовании. Обычно почта загружается на компьютер с пользовательским агентом, а не остается на почтовом сервере. Это облегчает жизнь серверу, но усложняет ее пользователю. Читать почту с нескольких компьютеров становится гораздо сложнее, к тому же, если компьютер с пользовательским агентом сломается, вся почта будет безвозвратно утеряна. Тем не менее POP3 все еще используется.

Кроме того, могут использоваться и частные протоколы, так как протокол работает между почтовым сервером и пользовательским агентом, который может обеспечиваться той же компанией. Примером почтовой системы с частным протоколом является Microsoft Exchange.

Таблица 7.8. Команды IMAP (версия 4)

Команда

Описание

CAPABILITY

Перечислить возможности сервера

STARTTLS

Запустить безопасный транспорт (TLS, см. главу 8)

LOGIN

Войти на сервер, используя имя пользователя и пароль

AUTHENTICATE

Авторизоваться иным способом

SELECT

Выбрать папку

EXAMINE

Выбрать папку, предназначенную только для чтения

CREATE

Создать папку

DELETE

Удалить папку

RENAME

Переименовать папку

SUBSCRIBE

Добавить папку к активному набору

UNSUBSCRIBE

Удалить папку из активного набора

LIST

Перечислить доступные папки

LSUB

Перечислить активные папки

STATUS

Узнать статус папки

APPEND

Добавить сообщение в папку

CHECK

Просмотреть состояние выбранной папки (что именно входит в понятие «состояние», зависит от конкретной реализации сервера). Создать контрольную точку для папки

FETCH

Просмотреть сообщения, находящиеся в папке

SEARCH

Найти сообщения, находящиеся в папке

STORE

Изменить метки сообщения

COPY

Сделать копию сообщения в папке

EXPUNGE

Удалить отмеченные сообщения

UID

Вызвать команды, используя уникальные идентификаторы

NOOP

Ничего не делать

CLOSE

Удалить помеченные сообщения и закрыть папку

LOGOUT

Выйти из системы и закрыть соединение

Веб-почта

Альтернативой IMAP и SMTP для предоставления почтовых услуг, набирающей все большую популярность, стало использование веб-интерфейса для отсылки и получения сообщений. Широко используемые системы веб-почты (Webmail) включают Google Mail, Microsoft Hotmail и Yahoo! Mail4. Веб-почта — это один из примеров программного обеспечения (в данном случае пользовательский почтовый агент), которое предоставляется как услуга, используя веб-технологии.

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

Мы пока не говорили о веб-технологиях в Интернете и о Всемирной паутине, но краткое описание выглядит примерно следующим образом: когда пользователь заходит на почтовую веб-страницу провайдера, он видит форму, в которой ему нужно заполнить поля Имя пользователя и Пароль. Пароль и имя пользователя отправляются на сервер, где проверяется их правильность. Если вход в систему осуществлен корректно, сервер находит почтовый ящик пользователя и строит веб-страницу, на которой отображается содержание почтового ящика. Эта веб-страница отсылается на браузер клиента.

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

7.3. Всемирная паутина (WWW)

Всемирная паутина (WWW, World Wide Web, часто для краткости просто «веб») — это архитектура, являющаяся основой для доступа к связанному контенту, находящемуся на миллионах машин по всему Интернету. За 10 лет своего существования из средства координации структуры экспериментов на тему физики высоких энергий в Швейцарии она превратилась в приложение, о котором миллионы людей с разными интересами думают, что это и есть «Интернет». Огромная популярность этого приложения стала следствием того, что даже новички не встречают затруднений при его использовании. Кроме того, при помощи цветного графического интерфейса Всемирная паутина предоставляет огромное количество информации практически по любому вопросу, от африканских муравьедов до яшмового фарфора.

Всемирная паутина была создана в 1989 году в Европейском центре ядерных исследований CERN (Conseil Europeen pour la Recherche Nucleaire) в Швейцарии. Сначала главной целью было наладить общение внутри больших групп, участники которых зачастую жили в разных странах и разных часовых поясах. Им нужно было пользоваться постоянно меняющимися отчетами о работе, чертежами, рисунками, фотографиями и другими документами, появляющимися по ходу ведения экспериментов в области физики элементарных частиц. Предложение создать паутину из связанных друг с другом документов пришло от физика центра CERN Тима Бернерс-Ли (Tim Berners-Lee). В декабре 1991 года на конференции Hypertext’91 в Сан-Антонио в штате Техас была произведена публичная демонстрация. Эта демонстрация привлекла внимание других ученых. Марк Андрессен (Marc Andreessen) в университете Иллинойса начал разработку первого графического браузера, Mosaic. Программа увидела свет в феврале 1993 года.

Остальное, как говорится, уже история. Mosaic стала настолько популярной, что год спустя ее автор Марк Андрессен решил сформировать собственную компанию Netscape Communications Corp., чьей целью была разработка программного обеспечения для Всемирной паутины (или короче — ПО для веб). В течение последующих трех лет между Netscape Navigator и Internet Explorer от Microsoft развернулась настоящая «война браузеров». Разработчики с той и с другой стороны в безумном порыве пытались заполучить как можно большую часть нового рынка, пичкая свои программы как можно большим числом функций (а следовательно, и ошибок), и в этом превзойти соперника.

На протяжении 1990-х и 2000-х годов количество веб-сайтов и веб-страниц, так же как и веб-контента, росло по экспоненте, пока количество сайтов не стало исчисляться миллионами, а количество страниц миллиардами. Небольшое число этих сайтов стало невероятно популярным. Эти сайты и стоящие за ними компании сегодня в серьезной мере определяют веб в том виде, в котором его видят люди. В качестве примеров можно перечислить: книжный магазин (Amazon, основанный в 1994 году, рыночная цена $50 млрд), блошиный рынок (eBay, 1995, $30 млрд), поисковик (Google, 1998, $150 млрд) и социальную сеть (Facebook, 2004, частная компания, оцениваемая более чем в $15 млрд). У того периода в 2000-х, когда стоимость многих веб-компаний подскочила до сотен миллионов долларов за одну ночь, только для того, чтобы обрушиться на следующий день (когда оказывалось, что их создание было просто рекламным ходом), даже есть имя. Он называется «эрой доткомов» (dot com era). Новые идеи до сих пор развиваются в веб подобным образом. Многие из них исходят от студентов. Например, Марк Цукерберг был студентом Гарварда, когда придумал и запустил проект Facebook, а Сергей Брин и Лари Пейдж были студентами Стенфорда, когда запустили Google. Возможно, вы будете следующим.

В 1994 году CERN и Массачусетский технологический институт (M.I.T., Massachusetts Institute of Technologies) подписали соглашение об основании WWW-консорциума (World Wide Web Consortium, иногда применяется сокращение W3C) — организации, цель которой заключалась в дальнейшем развитии Всемирной паутины, стандартизации протоколов и поощрении взаимодействия между отдельными сайтами. Бернерс-Ли стал директором консорциума. Хотя о Всемирной паутине уже написано очень много книг, лучшее место, где вы можете получить самую свежую информацию о ней, это сама Всемирная паутина. Домашнюю страницу консорциума можно найти по адресу http://www.w3.org. На этой странице заинтересованный читатель найдет ссылки на другие страницы, содержащие информацию обо всех документах консорциума и о его деятельности.

7.3.1. Представление об архитектуре

С точки зрения пользователя Всемирная паутина состоит из огромного количества контента в форме веб-страниц (Web pages), которые часто называются просто страницами (pages) для краткости. Каждая страница может содержать ссылки (указатели) на другие связанные с ней страницы в любой точке мира. Пользователи могут переходить по ссылке (например, просто щелкнув на ней мышью), при этом страница, на которую указывает ссылка, загружается и появляется в окне браузера. Этот процесс можно повторять бесконечно. Идея страниц, связанных между собой, ныне называемых гипертекстом (hypertext), была впервые пророчески предложена в 1945 году, задолго до появления Интернета, Ванневаром Бушем (Vannevar Bush), профессором из Массачусетского университета, занимавшимся электротехникой. На самом деле, это случилось даже до того, как появились коммерческие компьютеры, хотя в университетах уже существовали грубые прототипы, которые занимали огромные помещения, а по мощности уступали современным карманным калькуляторам.

Страницы просматриваются специальной программой, называемой браузером (browser). Самыми популярными браузерами являются программы Firefox, Internet Explorer и Chrome. Браузер предоставляет пользователю запрашиваемую страницу, интерпретирует ее контент и выводит должным образом отформатированные страницы на экран. Контент может быть представлен в виде сочетания текста, изображений и команд форматирования и выглядеть как обычный документ или как видео или программы с определенным графическим интерфейсом, в рамках которого может работать пользователь.

Пример веб-страницы дан в верхнем левом углу рис. 7.7. Это страница факультета информатики и вычислительной техники в Вашингтонском университете. На ней присутствуют текст и графические элементы (правда, не в том масштабе, чтобы все можно было хорошо разобрать). Некоторые части страницы связаны с другими страницами ссылками. Строки текста, значки, изображения и т. д., представляющие собой ссылки на другие страницы, называются гиперссылками (hyperlink). Чтобы перейти по ссылке, пользователь перемещает указатель мыши в выделенную область, при этом меняется форма указателя, и щелкает на ней. Переход по ссылке является просто сообщением браузеру того, что нужно загрузить другую страницу. Поначалу ссылки выделялись либо подчеркиванием, либо другим цветом, чтобы их можно было различить на странице. Сегодня создатели веб-страниц постоянно контролируют внешний вид ссылок, так что они могут быть выглядеть как значки, или менять внешний вид, когда в их области появляется курсор мышки. Сделать ссылки визуально отличимыми и обеспечить им подходящий интерфейс — задача создателей сайтов.

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

Таким образом, пользователь может постоянно перемещаться между компьютерами, просматривая контент.

Рис. 7.7. Архитектура Всемирной паутины

Основной принцип, стоящий за отображением страниц, также показан на рис. 7.7. Браузер отображает веб-страницу на клиентской машине. Каждая страница отображается посредством отсылки запроса на один или более серверов, который отвечает, передавая контент страницы. Протокол запроса-ответа для отображения страниц — это простой текстовый протокол, который работает через TCP, так же как и в случае с SMTP. Он называется HTTP (HyperText Transfer Protocol протокол передачи гипертекста). В качестве контента может выступать простой документ, который считывается с диска, или результат работы программы или запроса, отосланного в базу данных. Страница называется статичной (static page), если она представляет из себя статичный документ, который всегда отображается одинаково. Если страница, напротив, создается по требованию программы или сама содержит какую-либо программу, она называется динамической (dynamic page).

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

На рисунке браузер обращается к трем серверам, чтобы загрузить две страницы, cs.washington.edu, youtube.com и google-analytics.com. Контент с этих серверов интегрируется и отображается браузером. При отображении запускается обработка, тип которой зависит от типа контента. Кроме отображения текста и графических элементов, может возникнуть необходимость проиграть видеофайл или запустить скрипт, в котором прописан отдельный пользовательский интерфейс, являющийся частью страницы. В нашем случае с сервера cs.washington.edu загружается главная страница, с сервера youtube.com — размещенное на ней видео, а с сервера google-analytics.com — ничего из того, что видно пользователю; этот сервер ведет запись посетителей сайта. Позднее мы еще поговорим о трекерах.

Сторона клиента

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

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

1.    Как называется страница?

2.    Где она расположена?

3.    Как можно получить к ней доступ?

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

Избранное решение идентифицирует страницы таким образом, что сразу были решены все проблемы. Каждой странице был приписан URL (Uniform Resource Locator унифицированный указатель информационного ресурса), который служит именем страницы во Всемирной паутине. URL делится на три части: протокол (который также называют схемой scheme), DNS-имя машины, на которой расположена страница, и путь, уникально определяющий отдельную страницу (файл для чтения или программу, предназначенную для запуска на машине). В общем случае у пути есть иерархическое имя, которое моделирует структуру каталогов файлов. Однако интерпретация пути — это работа сервера. Действительная структура каталогов может и не отображаться.

В качестве примера приведем URL страницы, указанный на рис. 7.7: http://www.cs.washington.edu/index.html

Этот URL состоит из трех частей: протокола (http), DNS-имени хоста (www.cs.wa-shington.edu) и имени пути (index.html ).

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

1.    Браузер определяет URL (по выбранному элементу страницы).

2.    Браузер запрашивает у службы DNS IP-адрес сервера www.cs.washington.edu.

3.    DNS дает ответ 128.208.3.88.

4.    Браузер устанавливает TCP-соединение с 80-м портом (общеизвестным портом для HTTP-протокола) машины 128.208.3.88.

5.    Браузер отправляет HTTP-запрос на получение файла /index.html.

6.    Сервер www.cs.washington.edu высылает страницу, как HTTP-ответ, например, отправляя файл /index.html.

7.    Если страница содержит URL, которые необходимы для отображения, браузер получает другие URL, используя тот же процесс. В этом случае URL включают множество размещенных изображений, также полученных с www.cs.washington.edu, размещенное видео с youtube.com и скрипт с google-analitics.com.

8.    Браузер отображает страницу /index.html в том виде, в котором она представлена на рис. 7.7.

9.    Если в течение некоторого времени на те же серверы не поступает других запросов, TCP-соединения обрываются.

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

URL-дизайн не ограничен в том смысле, что он позволяет браузерам использовать различные протоколы для того, чтобы обрабатывать разные виды ресурсов. На самом деле, были определены URL и для многих других протоколов. Несколько упрощенные формы стандартных схем URL приведены в табл. 7.9.

Давайте коротко остановимся на этом списке. Протокол http — это родной язык Всемирной паутины, тот, на котором разговаривают веб-серверы. HTTP — это сокращение выражения HyperText Transfer Protocol (протокол передачи гипертекста). Мы поговорим о нем более детально немного позднее.

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

Таблица 7.9. Некоторые стандартные схемы URL

Имя

Используется

Пример

http

Гипертекст (HTML)

http://www.ee.uwa.edu/~rob/

https

Гипертекст с обеспечением безопасности

https://www.blank.com./accounts/

ftp

FTP

ftp://ftp.cs.vu.nl/pub/minix/README

file

Локальный файл

file:///usr/suzanne/prog.c

mailto

Отсылка почты

mailto:[email protected]

rtsp

Потоковая передача мультимедиа

rtsp://youtube.com/montypython.mpg

sip

Мультимедийный звонок

sip:[email protected]

about

Информация браузера

about:plugins

Можно получить доступ к локальному файлу как к веб-странице, используя протокол file или просто написав его имя. Для применения этого способа не нужен сервер. Конечно, это работает только для локальных файлов, а не для удаленных.

Протокол mailto, на самом деле, не позволяет запрашивать веб-страницы, но он все равно полезен. С его помощью можно отсылать почту через веб-браузер. Большинство браузеров отвечают на переход пользователя по ссылке mailto запуском пользовательского агента, в котором можно начинать писать сообщение с уже добавленным адресом.

Протоколы rtsp и sip предназначены для установления сессий передачи мультимедийных потоков, а также аудио- и видеозвонков.

Наконец, протокол about предоставляет информацию о браузере. Например, если вы пройдете по ссылке about:plugins, большинство браузеров отобразит страницу, перечисляющую типы MIME, которые доступны благодаря расширениям браузера (так называемым плагинам).

Вкратце, URL были разработаны не только для навигации во Всемирной паутине, но и для того, чтобы запускать более старые протоколы, такие как FTP и электронная почта, и новые для аудио и видео и, конечно, для того, чтобы предоставить удобный доступ к локальным файлам и информации браузера. Благодаря этому подходу теряется необходимость во всех программах, предоставляющих пользовательский интерфейс для вышеперечисленных нужд, а доступ в Интернет практически полностью интегрируется в одну программу: веб-браузер. Если бы не тот факт, что эта идея пришла в голову британского физика, работающего в исследовательской лаборатории в Швейцарии, можно было бы легко предположить, что это был прекрасный план, разработанный рекламным отделом компании, выпускающей программное обеспечение.

Несмотря на все эти выдающиеся качества, постоянно увеличивающееся использование Всемирной паутины выявило некоторые недостатки, заложенные в схему URL.

URL указывает на один отдельный хост, но иногда имеет смысл ссылаться на страницу, не указывая того, где она находится. Например, было бы неплохо, если бы страницы, на которые идет множество ссылок, многократно копировались в разных частях сети, чтобы уменьшить трафик. Но мы не можем сказать: «Мне нужна страница xyz и мне все равно, откуда она возьмется».

Чтобы решить эту проблему, URL были обобщены до URI (Uniform Resource Identifier универсальный идентификатор ресурса). Некоторые URI указывают, как определить место нахождения ресурса. Это URL. Другие URI указывают имя ресурса, но не место его нахождения. Эти URI называются URN (Uniform Resource Name — унифицированное имя ресурса). Правила написания URI отражены в RFC 3986, другие схемы использования URI определяются IANA. Существует много различных типов URI, помимо перечисленных в табл. 7.9; мы перечислили только те, что сегодня наиболее часто используются во Всемирной паутине.

Типы MIME

Для отображения новой (и каждой) страницы браузер должен понять ее формат. Чтобы все браузеры могли отображать любые страницы, они пишутся на стандартизованном языке HTML. На сегодняшний день он является общепринятым в Интернете. Более детально мы рассмотрим его ниже.

Несмотря на то что браузер по сути дела представляет собой интерпретатор HTML, большинство браузеров оснащается многочисленными кнопками и функциями, облегчающими навигацию по Всемирной паутине. У многих браузеров есть кнопки для возврата на предыдущую страницу и перехода на следующую страницу (последняя доступна только в том случае, если пользователь уже возвращался назад), а также кнопка для прямого перехода на выбранную пользователем начальную страницу. Большинство браузеров поддерживают в меню команды для установки закладки на текущей странице и отображения списка закладок, что позволяет попадать на любую страницу при помощи всего одного щелчка мышью.

Как показано в нашем примере, HTML-страницы могут содержать разнообразные элементы контента, а не только текст и гипертекст. Строго говоря, не всем страницам необходимо содержать HTML. Страница может содержать видео в формате MPEG, документ в формате PDF, фотографию в формате JPEG, песню в формате MP3 и еще сотни различных типов файлов. Поскольку стандартные HTML-страницы могут иметь ссылки на любые файлы, у браузера возникает проблема обработки страницы, которую он не может интерпретировать.

Вместо того чтобы наращивать возможности и размеры браузеров, встраивая в них интерпретаторы для различных типов файлов (количество которых быстро растет), обычно применяется более общее решение. Когда сервер возвращает в ответ на запрос какую-либо страницу, вместе с ней высылается некоторая дополнительная информация о ней. Эта информация включает MIME-тип страницы (см. табл. 7.6). Страницы типа text/html выводятся браузером напрямую, как и страницы некоторых других встроенных типов. Если же для данного MIME-типа внутренняя интерпретация невозможна, браузер определяет, как выводить страницу, по своей таблице MIME-типов. В данной таблице в соответствие каждому типу ставится программа просмотра.

Существует два способа отображения: с помощью подключаемого модуля, плагина (plug-in), или вспомогательных приложений. Подключаемый модуль представляет собой особый сторонний код, который браузер извлекает из специального каталога на жестком диске и устанавливает в качестве своего расширения, как показано на рис. 7.8, а. Стандартными примерами являются плагины для PDF, Flash и Quick-time, позволяющие работать с документами и проигрывать аудио и видео. Поскольку подключаемые модули работают внутри браузера, у них есть доступ к текущей странице, вид которой они могут изменять. После завершения своей работы (обычно это связано с переходом пользователя на другую страницу), подключаемый модуль удаляется из памяти браузера.

Рис. 7.8. Браузер с подключаемым модулем (а); вспомогательное приложение (б)

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

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

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

Вторым способом расширения возможностей браузера является использование вспомогательных приложений (helper application). Вспомогательное приложение — это полноценная программа, работающая как отдельный процесс. Это показано на рис. 7.8, б. Поскольку она никак не связана с браузером, между ними отсутствует какой бы то ни было интерфейс. Вспомогательное приложение обычно принимает от браузера имя временного файла, содержащего данные для отображения, открывает файл и отображает контент. Обычно в роли вспомогательных приложений выступают большие программы, которые существуют отдельно от браузера, например Microsoft Word или PowerPoint.

Многие вспомогательные приложения используют MIME-тип application (приложение). В результате было определено существенное число подтипов, например application/vnd.ms-powerpoint для файлов PowerPoint; vnd обозначает формат, зависящий от поставщика. Таким образом, URL может напрямую указывать на файл PowerPoint, и когда пользователь щелкает на нем, автоматически загружается PowerPoint, обрабатывает нужный файл и отображает его. Вспомогательные приложения могут пользоваться не только MIME-типом application. Так, например, Adobe Photoshop использует image/x-photoshop.

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

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

Браузеры могут работать и с локальными файлами без соединения с сетью, не запрашивая информацию с удаленных серверов. Однако браузеру нужно каким-то хитрым образом определить MIME-тип файла. Стандартный метод заключается в ассоциировании на уровне операционной системы расширения файла с типом MIME. В стандартной конфигурации попытка открыть файл foo.pdf приведет к его открытию в браузере с использованием плагина application/pdf, а файл bar.doc будет открыт во вспомогательном приложении Word.

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

Расширение возможностей браузера по поддержке новых типов файлов — это удобно, но может также привести к возникновению некоторых проблем. Когда браузер на компьютере с Windows получает файл с расширением exe, он думает, что это исполняемая программа и никаких вспомогательных средств для нее не требуется. Очевидно, следует просто запустить программу. Однако такой подход может оказаться серьезной дырой в системе защиты информации. Злоумышленнику требуется лишь создать нехитрый сайт с фотографиями, скажем, знаменитых киноактеров или спортсменов, и поставить ссылки на вирусы. Один-единственный щелчок мышкой на фотографии может в этом случае привести к запуску непредсказуемой и, возможно, опасной программы, которая будет действовать на машине пользователя. Для предотвращения подобных нежелательных ситуаций Firefox и другие программы настроены на избирательный запуск неизвестных программ, однако не все пользователи понимают, что безопасный выбор важнее удобного.

Сторона сервера

О стороне клиента сказано уже достаточно много. Поговорим теперь о стороне сервера. Как мы уже знаем, когда пользователь вводит URL или щелкает на гиперссылке, браузер производит структурный анализ URL и интерпретирует часть, заключенную между http:// и следующей косой чертой, как имя DNS, которое следует искать. Вооружившись IP-адресом сервера, браузер устанавливает TCP-соединение с 80 портом этого сервера. После этого отсылается команда, содержащая оставшуюся часть URL, в которой указывается путь к странице на сервере. Сервер возвращает браузеру запрашиваемый файл для отображения.

В первом приближении простой веб-сервер напоминает сервер, представленный в листинге 6.1. Этому серверу, как и настоящему веб-серверу, передается имя файла, который следует найти и отправить по сети. В обоих случаях в основном цикле сервер выполняет следующие действия:

1.    Принимает входящее TCP-соединение от клиента (браузера).

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

3.    Получает файл (с диска).

4.    Высылает содержимое файла клиенту.

5.    Разрывает TCP-соединение.

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

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

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

Одним из способов решения проблемы последовательной обработки запросов является создание многопоточных (multithreaded) серверов. Одна из реализаций подразумевает, что сервер состоит из входного модуля, принимающего все входящие запросы, и k обрабатывающих модулей, как показано на рис. 7.9. Все k + 1 потоков принадлежат одному и тому же процессу, поэтому у обрабатывающих модулей есть доступ к кэшу в адресном пространстве процесса. Когда приходит запрос, входящий модуль принимает его и создает краткую запись с его описанием. Затем запись передается одному из обрабатывающих модулей.

Рис. 7.9. Многопоточный веб-сервер с входным и обрабатывающими модулями

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

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

Современные веб-серверы выполняют гораздо больше функций, чем просто прием имен путей и отправка файлов. На самом деле, реальная обработка каждого запроса может оказаться достаточно сложной. По этой причине на многих серверах каждый обрабатывающий модуль выполняет последовательности действий. Входной модуль передает каждый входящий запрос первому доступному модулю, который обрабатывает его путем выполнения некоторого подмножества указанных ниже шагов, в зависимости от того, что именно требуется для данного запроса. Эти шаги появляются после того, как было создано TCP-соединение и какой-либо защищенный транспортный механизм (как SSL/TLS, который будет описан в главе 8).

1.    Вычисление имени запрашиваемой веб-страницы.

2.    Осуществление контроля доступа для веб-страницы.

3.    Проверка кэша.

4.    Получение запрошенной страницы с диска или запуск программы, создающей ее.

5.    Определение оставшейся части ответа (например, типа MIME).

6.    Возвращение ответа клиенту.

7.    Добавление записи в журнал активности сервера.

Шаг 1 необходим, потому что входящий запрос может и не содержать реального имени файла или программы в виде строкового литерала. Он может содержать встроенные ярлыки, которые необходимо передать. Например, URL может быть вот таким: http://www.cs.vu.nl/. Здесь имя файла отсутствует. Этот URL необходимо дополнить неким именем файла по умолчанию. Обычно это index.html. Другое общее правило — отображать ~user/ в веб-каталог пользователя. Эти правила могут быть использованы вместе. Таким образом, домашняя страница одного из авторов (AST) будет доступна по адресу:

http://www.sc.vu.nl/~ast/

несмотря на то что реальным именем файла является index.html в определенном каталоге. К тому же современные браузеры могут указывать информацию о конфигурации, такую как язык пользователя и ПО браузера по умолчанию (например, итальянский или английский), что позволяет серверу выбирать веб-страницу с маленькими картинками для мобильного устройства на соответствующем языке, если таковая существует. Вообще говоря, расширение имени — задача не такая уж тривиальная, как может показаться, поскольку существует множество соглашений о том, как отображать пути в файловые каталоги и программы.

Шаг 2 состоит в проверке наличия ограничений доступа, ассоциированных со страницей. Не все страницы доступны широкой публике. Определение того, имеет ли право клиент просматривать страницу, может зависеть от личности клиента (например, заданной при помощи имени пользователя и пароля) или расположения клиента в пространстве DNS или IP. Например, право просмотра страницы могут иметь только сотрудники какой-либо компании. То, как это достигается, зависит от устройства сервера. Так, на популярном сервере Apache в каталоге, в котором расположены файлы с ограничением доступа, существует файл под названием .htaccess, перечисляющий эти ограничения.

Шаги 3 и 4 подразумевают получение страницы. Правила обработки определяют, можно ли ее получить из кэша. Например, страницы, созданные работающими программами, не всегда могут сохраняться в кэше, так как при каждом запуске они могут выдавать различные результаты. Время от времени должны проверяться даже файлы, чтобы выяснить, не изменилось ли их содержимое (тогда старые версии можно будет удалить из кэша). Если страница требует запуска программы, также возникает проблема с определением параметров программы или входных данных. Эти данные извлекаются из пути или других частей запроса.

На шаге 5 определяются другие части ответа, связанные с содержимым страницы. Например, MIME-тип. Он может следовать из расширения файла, файла конфигурации и, возможно, других источников.

Шаг 6 возвращает страницу по сети. Чтобы повысить производительность, одно и то же TCP-соединение может быть использовано клиентом и сервером для многократного получения различных страниц. Такой тип использования предполагает создание некоторой логики для отображения запроса на совместно используемое соединение и возвращения каждого ответа таким образом, чтобы он ассоциировался с нужным запросом.

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

Файлы cookie

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

Эта модель прекрасно подходит для получения документов, предназначенных для широкой публики, и она хорошо работала в то время, когда Всемирная паутина была только создана. Однако такой вариант не подходит для возвращения различных страниц разным пользователям в зависимости от того, что они уже сделали с сервером. Такое поведение необходимо для многих непрерывных взаимодействий с веб-сайтами. К примеру, на некоторых сайтах (например, сайтах газет) требуется регистрация пользователей; а иногда получение информации с сайта является платным. Возникает вопрос различения запросов от зарегистрированных пользователей и от всех остальных. Вторым примером является электронная коммерция. Как серверу собрать информацию о состоянии корзины пользователя, если тот время от времени пополняет ее содержимое? Третий пример — веб-порталы типа Yahoo!. Пользователям предоставляется возможность индивидуально настраивать вид начальной страницы (например, так, чтобы им сразу показывались последние новости о любимой спортивной команде или курсы ценных бумаг). Однако как сервер сможет корректно отобразить страницу, если он не знает, с каким пользователем имеет дело?

На первый взгляд может показаться, что решение очевидно: сервер может различать пользователей по их IP-адресам. Однако эта идея не работает. Во-первых, многие пользователи работают на компьютерах с разделяемыми ресурсами (например, дома), и с помощью IP-адреса можно идентифицировать лишь компьютер, а не пользователя. Что еще хуже, многие компании используют NAT, поэтому исходящие пакеты от всех клиентов имеют один и тот же IP-адрес. То есть все компьютеры, которые работают через NAT, кажутся серверу одинаковыми. К тому же многие ISP приписывают IP-адреса посетителям при помощи DHCP. IP-адрес со временем может измениться, так что для сервера вы внезапно станете выглядеть так же, как ваш сосед. По всем этим причинам сервер не может использовать IP-адрес, чтобы отслеживать пользователей.

Для решения этой проблемы был предложен сильно раскритикованный метод cookie-файлов. Такое название произошло от старинного программистского сленгового словечка. Программа вызывала процедуру и получала взамен нечто, что могло понадобиться впоследствии для выполнения какой-либо задачи. Это «нечто» и называлось cookie. В этом смысле файловый дескриптор в UNIX и дескриптор объектов в Windows можно рассматривать как cookie. Эти специальные маркеры были впервые применены в браузере Netscape в 1994 году. Сейчас они формализованы в RFC 2109.

Когда пользователь запрашивает страницу, сервер может снабдить свой ответ дополнительной информацией в форме cookie-файла, который представляет собой маленькую именованную строку (до 4 Кб), которую сервер может ассоциировать с браузером. Эта ассоциация не позволяет наверняка определить пользователя, но она является гораздо более точной, чем IP-адрес. Браузеры обычно на некоторое время сохраняют полученные маркеры в каталоге cookie на жестком диске клиента, так что cookie-файлы сохраняются при повторных вызовах браузера, если только пользователь не отключил данную функцию. Итак, cookie — это файлы или строки, а не исполняемые программы. В принципе, в них может содержаться вирус, но поскольку они рассматриваются всего лишь как информационные данные, нет какой-либо официальной возможности для активации вирусов и нанесения ущерба системе. Однако у хакера всегда есть возможность, используя ошибки в браузере, заставить активироваться вирусы, содержащиеся в cookie.

В маркерах cookie может содержаться до пяти полей, как показано в табл. 7.10. Поле Домен (Domain) содержит имя домена, с которого пришел маркер. Предполагается, что браузеры проверяют тот факт, что серверы не лгут относительно имен доменов. Каждый домен должен хранить не более 20 маркеров, связанных с одним клиентом. Поле Путь (Path) содержит путь в структуре каталогов на сервере, указывающий те части дерева каталогов, которые могут использовать маркер. Часто в этом поле содержится знак «/», означающий, что доступно дерево целиком.

Поле Содержимое (Content) имеет вид имя = значение. Как имя, так и значение могут быть совершенно произвольными, на усмотрение сервера. В этом поле хранится основная информация, которую несет в себе маркер.

Поле Годен до (Expires) указывает срок годности маркера. Если это поле отсутствует, браузер отбрасывает cookie сразу после выхода из программы. Такой маркер называется непостоянным (nonpersistent cookie). Если же указано время и дата, то о таком маркере говорят, что он постоянный (persistent cookie). Он хранится до тех пор, пока не выйдет срок годности. Время, указываемое в поле Годен до, — гринвичское. Чтобы удалить cookie с жесткого диска клиента, сервер просто посылает его заново, указывая вышедший срок годности.

Таблица 7.10. Несколько примеров cookie

Наконец, поле Защищенный (Secure) может быть установлено для индикации того, что браузер может вернуть его только на сервер, использующий защищенный канал передачи информации, а именно SSL/TLS (который мы опишем в главе 8). Это свойство используется в электронной коммерции, банковском деле и других приложениях, в которых важна защита информации.

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

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

Второй cookie-маркер пришел сjills-store.com. Сценарий в этом случае заключается в том, что клиент бродит по магазину, выбирая себе покупки. Найдя что-нибудь привлекательное, он щелкает на значке товара. При этом сервер добавляет товар к списку покупок (который поддерживается на сервере), а также создает cookie-маркер, содержащий код заказанного товара, и отсылает cookie клиенту. Клиент продолжает бродить по электронному магазину, щелкая мышью на новых страницах, и в ответ на каждый новый запрос страницы на сервер отсылается cookie. По мере накопления выбранных товаров дополняется информация в cookie. Наконец, когда пользователь щелкает ПЕРЕЙТИ К РАСЧЕТАМ, cookie, содержащий теперь уже полную информацию о покупках, отсылается вместе с запросом на сервер. Таким образом, серверу точно известно, какие товары хочет приобрести клиент.

Третий cookie-маркер прибыл с веб-портала. Когда пользователь щелкает по ссылке на портал, браузер отсылает ему cookie, в котором говорится о том, что надо показать страницу, содержащую котировки акций Cisco и Oracle, а также результаты футбольного матча New York Jets. Так как максимальный размер cookie-файла равен 4 Кб, то остается еще много места для более детальной настройки страницы. Например, в нее можно включить сводку погоды, специальные предложения, заголовки статей в крупных газетах и т. п.

Более спорным использованием cookie-файлов является отслеживание действий пользователя. Операторы веб-сайтов узнают, как пользователи перемещаются по их страницам, и рекламщики строят профили сайтов и реклам, которые просматривал отдельный пользователь. Загвоздка заключается в том, что пользователи обычно не знают, что их поведение отслеживается, даже в случае детализированных профилей и веб-сайтов, которые кажутся несвязанными. Тем не менее веб-отслеживание (Web-tracking) является серьезным бизнесом. Doubleclick, который предоставляет и отслеживает рекламные баннеры, признан компанией Alexa, занимающейся вебмониторингом, одним из 100 крупнейших веб-сайтов в мире. Google Analitics, отслеживающий использование сайтов для операторов, используется более чем половиной из крупнейших 100 000 сайтов.

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

Отслеживание навигации пользователей по сайтам является чуть более сложной задачей. Это делается так. Рекламное агенство, скажем, Черный Рекламщик, связывается с крупнейшими веб-сайтами и размещает на них рекламные баннеры продуктов своих клиентов, за что сайту выплачиваются денежные взносы. Вместо того чтобы предоставлять сайту баннер в виде GIF с рекламой, который можно разместить на каждой из страниц, ему дается URL, который следует поместить на всех страницах. Каждый из этих URL содержит уникальный идентификатор в виде пути, например: http://www.sneaky.com/382674902342.gif

Когда пользователь впервые посещает страницу Р, содержащую такую рекламу, браузер, как водится, принимает HTML-файл. Просматривая его, браузер находит ссылку на изображение на www.sneaky.com. Разумеется, он отправляет запрос на получение изображения. Вместе с GIF приходит cookie с уникальным идентификатором пользователя, 4627239101 (см. табл. 7.10). Черный Рекламщик отмечает, таким образом, тот факт, что пользователь с таким идентификатором посетил страницу Р. Это делается очень просто, так как ссылка на запрошенный файл (382674902342.gif) существует, на самом деле, только на странице Р. Конечно, одна и та же реклама может располагаться на тысячах разных страниц, но каждая из них имеет свое имя. При этом за доставку каждого экземпляра рекламная компания может взимать с заказчика небольшую сумму.

Затем, когда пользователь оказывается на другой странице, содержащей баннер от Черного Рекламщика, браузер, скачав HTML-файл с сервера, видит ссылку на изображение с именем, скажем, http://www.sneaky.com/193654919923.gif, и запрашивает данный файл. Поскольку с домена sneaky.com уже был получен cookie, браузер отсылает его обратно с идентификатором пользователя. Так Черный Рекламщик (ЧР) узнает о том, что пользователь посетил вторую страницу с его рекламой.

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

И если ЧР хочет стать Суперчерным Мегарекламщиком, его объявления не должны выглядеть как обычные классические баннерные ссылки. «Объявление» размером в один пиксел, сливающееся по цвету с задним фоном страницы (то есть невидимое), будет иметь ровно такой же эффект при слежении за пользователями: браузер будет запрашивать gif-изображение размером 1 х 1 пиксел и отправлять обратно cookie.

Cookie стали центральной точкой дебатов по поводу конфиденциальности в сети из-за описанного выше отслеживания поведения пользователей. Наиболее коварной частью всего бизнеса является то, что многие пользователи не имеют не малейшего представления о том, что идет сбор какой-то информации, и даже могут считать, что они защищены от подобного, так как не щелкают мышью ни на какие баннеры. По этой причине cookie, которые отслеживают поведение пользователей на сайтах, многими воспринимаются как программы-шпионы (spyware). Посмотрите на cookie, которые уже хранятся в вашем браузере. Большинство браузеров покажет эту информацию вместе с текущими настройками конфиденциальности. Кроме непонятных идентификаторов вы можете с удивлением обнаружить имена, адреса и пароли. Будем надеяться, что номеров кредитных карт там не будет, но потенциальные возможности злоупотребления информацией очевидны.

Для самоуспокоения некоторые пользователи настраивают свои браузеры так, чтобы они отвергали любые cookie. Однако это может породить проблемы, так как многие веб-сайты не смогут корректно работать без обмена с пользователями cookie-маркерами. Помимо этого большинство браузеров позволяет пользователям блокировать cookie «третьей стороны» (third-party cookies). То есть те, которые исходят не с сайта, на главной странице которого вы находитесь, например cookie sneaky.com, который используется при взаимодействии со страницей P, а с совершенно другого веб-сайта. Блокирование этих cookie позволяет избежать отслеживания переходов между сайтами. Также для обеспечения надлежащего контроля за тем, как используются (или не используются) cookie, можно инсталлировать расширения браузеров. Пока продолжаются споры, многие компании разрабатывают варианты политики конфиденциальности, которые определяют то, каким образом они будут делиться информацией, чтобы избежать злоупотреблений. Конечно, такая политика определяет лишь то, как компании формулируют взаимодействие с получаемой информацией. Например, фраза «Мы можем использовать собранную о вас информацию в собственных целях» может означать, что компания может ее продать.

7.3.2. Статичные веб-страницы

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

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

HTML — язык разметки веб-страниц

HTML (HyperText Markup Language) появился параллельно со Всемирной паутиной. С помощью HTML можно размещать на веб-страницах текст, графику, видео, а также указатели на другие страницы и т. п. Он является языком разметки, то есть языком, описывающим способ форматирования документа. Термин «разметка» (markup) восходит к тем дням, когда литературный редактор с помощью специальной разметки указывал типографу (это такой человек когда-то был), какой шрифт использовать для печати документа. Таким образом, языки разметки содержат подробные команды форматирования. Например, в языке HTML команда означает начало участка текста, печатаемого полужирным шрифтом, а означает конец такого участка. Другими примерами языков разметки, хорошо известными академическим авторам, являются LaTeX и TeX.

Главное преимущество языка разметки перед языком, не имеющим явных команд форматирования, заключается в том, что он отделяет контент от того, каким образом он должен быть представлен. Таким образом, написание браузера является простой задачей: браузер должен понимать и применять содержащиеся в тексте команды разметки к контенту. С помощью встроенных стандартизированных команд разметки в HTML-файлах становится возможным читать и переформатировать любую вебстраницу веб-браузером. Способность изменять форматирование крайне важна, так как должна быть возможность просматривать веб-страницу, созданную на экране с установленным разрешением 1600 х 1200 точек при 24 битах на точку, на экране с разрешением, например, 640 х 320 точек при 8 битах на точку на мобильном телефоне.

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

Простая веб-страница, написанная на HTML, и то, как она выглядит в браузере, показано на рис. 7.10. Страница состоит из заголовка и тела. Вся страница размещается между командами форматирования, называемыми в языке HTML тегами (tags),  и . Впрочем, большинство браузеров правильно отобразят страницу и в отсутствие этих тегов. Как видно из рис. 7.10, а, заголовок веб-страницы заключен в скобки тегов и , а тело располагается между тегами и . Команды внутри тегов называют директивами (directives). Пусть не все, но большинство HTML-тегов имеют такой формат, то есть помечает начало чего-либо, а — его конец.

Регистр символов в тегах не имеет значения. Например, и означают одно и то же, однако у нижнего регистра лучше характеристики совместимости. Формат самого HTML-текста, то есть расположение строк и т. д., не имеет значения. Программы обработки HTML-текстов игнорируют лишние пробелы и переносы строк, так как они все равно форматируют текст так, чтобы он помещался в заданной области

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

Рис. 7.10. HTML для примера веб-страницы (а). Отформатированная страница (б)

Некоторые теги могут иметь именованные параметры, называемые атрибутами (attributes). Например, тег на рис. 7.10 используется для того, чтобы наравне с текстом расположить на странице изображение. У этого тега есть два атрибута src и alt. Первый атрибут предоставляет URL для изображения. HTML-стандарт не определяет, какие форматы изображений разрешены. На самом деле, практически все

браузеры поддерживают файлы GIF и JPEG. Браузеры могут поддерживать и другие форматы, но это палка о двух концах. Если пользователь привык к браузеру, который поддерживает, скажем, файлы TIFF, он может разместить их на своих веб-страницах, а потом с удивлением обнаружить, что другие браузеры просто игнорируют все эти замечательные картинки.

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

Формально при написании HTML-документов должен использоваться набор символов Latin-1 международного стандарта ISO 8859-1, но для пользователей, чьи клавиатуры поддерживают только ASCII-символы, для ввода специальных символов, таких как, например, е, могут использоваться специальные управляющие последовательности символов. Эти последовательности должны начинаться со знака амперсанда и заканчиваться точкой с запятой. Например,   означает пробел, è означает символ е, а é — символ е. Так как сами символы <, > и & оказываются зарезервированными, для их отображения в тексте также применяются управляющие последовательности: < (less than — знак «меньше»), > (greater than — знак «больше») и & (ampersand — амперсанд).

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

Несколько заголовков используются на рис. 7.10. Каждый из них создается при помощи тега вида , где n — цифра от 1 до 6.

является самым важным заголовком,

— наименее важным. Как это отобразить на экране, зависит от браузера. Обычно заголовки с меньшими номерами отображаются более крупными шрифтами. Браузер может также выделять различные заголовки различными цветами. Обычно заголовки

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

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

Теги и обозначают соответственно полужирный шрифт (boldface) и курсив (italics). При использовании тега


отображается разрыв, а также горизонтальная черта на странице.

Тегом

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

, обозначающим конец абзаца.

Язык HTML предоставляет несколько механизмов создания списков, включая вложенные списки. Неупорядоченные списки (unordered list), такие как на рис. 7.10, начинаются тегом

    . Отдельные пункты раньше помечались тегом
  • . Тег
       (ordered list) соответствует упорядоченному списку. При его использовании абзацы, отдельные пункты неупорядоченного списка помечаются знаком «•». Элементы упорядоченных списков автоматически нумеруются браузером.

И наконец, мы подошли к гиперссылкам. Примеры их использования вы можете увидеть на рис. 7.10. Гиперссылки вводятся при помощи пары тегов: (anchor — закладка) и . У этого тега также могут быть различные параметры, самым значимым из которых является href (гиперссылка, URL). Текст, располагающийся между тегами  и , отображается на экране. Если этот текст выбирается, браузер открывает страницу, на которую указывает гиперссылка. Между тегами и можно также размещать и другие элементы, например изображение (тег ). В этом случае, если пользователь щелкнет на изображении, будет произведен переход по ссылке.

Существует множество других тегов и атрибутов HTML, которые мы не привели в этом простом примере. Так, тег может содержать параметр name, что позволяет создать гиперссылку посреди текста, на которую можно ссылаться из другого места этой же страницы. Это может быть полезным в том случае, если веб-страницы начинаются с оглавления, состоящего из «локальных» гиперссылок. Щелчок мышью на пункте оглавления позволяет быстро переместиться в нужное место страницы. В качестве другого примера можно привести тег
. Он заставляет браузер вставить перевод строки.

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

Мы вкратце рассказали о тегах, которые существуют с ранних этапов развития Всемирной паутины. HTML продолжает развиваться. В табл. 7.11 отображены некоторые возможности, которые были добавлены в следующих версиях HTML. HTML 1.0 относится к версии HTML, которая использовалась при возникновении Всемирной паутины. Версии 2.0, 3.0 и 4.0 сменяли друг друга достаточно быстро в течение нескольких лет после того, как Всемирная паутина обрела популярность. После HTML 4.0 прошло почти десять лет, прежде чем путь для новой версии, HTML 5.0, был открыт. Так как данный стандарт является основным обновлением, объединяющим способы, которыми браузеры обрабатывают разнообразный контент, HTML 5.0 до сих пор находится в стадии разработки, которая вряд ли закончится раньше 2012 года. Тем не менее основные браузеры уже поддерживают возможности HTML 5.

Изменения, вносимые в версии HTML, связаны с добавлением новых возможностей, которые люди хотели бы видеть, но пока они не вошли в стандарт, использовать данные возможности приходится нестандартным образом (например, при помощи плагинов). Так, например, в первых двух версиях не существовало таблиц, они были добавлены только в HTML 3.0. HTML-таблица состоит из нескольких строк, каждая из которых состоит из нескольких ячеек, которые могут содержать широкий спектр данных (например, текст, изображения и даже другие таблицы). До введения HTML 3.0 авторам, которым нужна была таблица, приходилось прибегать к особым методам, таким как включение картинки, на которой изображалась таблица.

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

Таблица 7.11. Некоторые отличия между версиями HTML

Объект

HTML 1.0

HTML 2.0

HTML 3.0

HTML 4.0

HTML 5.0

Гиперссылки

X

X

X

X

X

Изображения

X

X

X

X

X

Списки

X

X

X

X

X

Активные карты и изображения

X

X

X

X

Формы

X

X

X

X

Математические формулы

X

X

X

Панели инструментов

X

X

X

Таблицы

X

X

X

Возможности по обеспечению доступности

X

X

Встраивание объектов

X

X

Таблицы стилей

X

X

Скрипты

X

X

Видео и аудио

X

Векторная графика

X

Отображение XML

X

Фоновые потоки

X

Хранение информации в браузере

X

Область для рисования

X

HTML 5.0 включает множество опций, предназначенных для обработки мультимедиа, которое на сегодняшний день широко используется во Всемирной паутине. Видео и аудио может размещаться на страницах и проигрываться браузером, и это не потребует от пользователя установки плагинов. Вместо использования растровых форматов графических объектов (таких как JPEG и GIF), можно строить рисунки в браузере в виде векторной графики. Также расширились возможности поддержки выполнения скриптов в браузерах, таких как фоновые потоки вычислений и доступ к хранилищу. Все эти возможности помогают поддерживать веб-страницы, которые больше похожи на традиционные приложения с пользовательским интерфейсом, чем на документы. Именно в этом направлении развивается Всемирная паутина.

Ввод информации и формы

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

Отсылка вводимой информации от пользователя серверу (через браузер) требует двух типов поддержки. Во-первых, необходимо, чтобы HTML передавал данные в этом направлении. То, как это происходит, мы опишем в следующем разделе; в этом процессе задействован метод POST. Во-вторых, нужно предоставить элементы пользовательского интерфейса, которые собирают и пакуют вводимую информацию. Формы (forms) с этой функциональностью были введены в HTML 2.0.

Формы могут содержать кнопки и поля для ввода текста, позволяющие пользователям делать выбор или вводить необходимую информацию, которую затем можно отсылать владельцу страницы. Формы написаны так же, как и другие части HTML, как видно из примера в листинге 7.4. Внешний вид формы, соответствующей данному HTML-тексту, приведен на рис. 7.11. Обратите внимание на то, что формы являются статическим контентом. Они не меняют поведения в зависимости от того, кто их использует. Динамический контент, о котором мы поговорим позднее, предоставляет более сложные способы сбора вводимой информации при помощи пересылки программы, поведение которой может зависеть от среды браузера.

Как и все формы, она заключена между тегами

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

В данной форме для ввода данных используются три типа окон, каждый из которых использует тег . У данного тега есть множество параметров для определения размера, особенностей и использования отображаемой области. Самые распространенные формы — это пустые поля, в которые пользователь может ввести текст, флажки и кнопки «отправить», которые инициируют передачу данных на сервер.

Окно первого типа — это текстовая область, которая следует за текстом «Имя». Ширина этого окна 46 символов. Предполагается, что пользователь введет здесь свое имя, которое будет храниться в виде текстовой строки в переменной customer для последующей обработки. В следующих окнах формы спрашивается адрес заказчика, то есть улица, город, штат и страна. Так как между этими полями не вставляются теги

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

Следом за датой истечения срока действия кредитной карты мы обнаруживаем новые для нас элементы управления — переключатели. Они используются, когда требуется выбрать только один вариант из нескольких. Они напоминают кнопки на автомагнитолах, служащие для быстрого доступа к заданным радиостанциям. Переключатели этого типа всегда объединяются в группы. При этом включение одного переключателя автоматически выключает все остальные переключатели этой группы. Внешний вид переключателя зависит от используемого графического интерфейса. В пункте бланка «Размер штуковины» также используется два переключателя. Группы переключателей определяются по значению параметра name (имя) тега . Специальных скобок из тегов, вроде ... , для определения групп переключателей не предусмотрено.

Параметры value указывают, какая кнопка была нажата пользователем. Например, в зависимости от того, какую кредитную карту выберет пользователь для своих расчетов, переменной сс будет присвоено значение текстовой строки «mastercard» или «visacard».

Листинг 7.4. HTML-текст для бланка заказа

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

Наконец, мы добираемся до кнопки, имеющей тип submit (подтверждение). Строка параметра value в данном случае содержит надпись на кнопке. Когда пользователь нажимает кнопку submit, браузер упаковывает всю собранную информацию в одну большую строку и отправляет ее на сервер, на URL, прописанный как часть тега

, для обработки. Используется простой способ кодировки. Поля с данными разделяются амперсандами (&), а вместо пробелов ставятся знаки +. В нашем примере такая строка, отсылаемая на сервер, может выглядеть так, как показано ниже в листинге 7.5.

Рис. 7.11. Форматированная страница бланка заказа

Листинг 7.5. Возможный ответ браузера серверу, содержащий введенную пользователем информацию.

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

Есть и другие типы вводимой информации, которые не приведены в этом простом примере. Так, например, существуют типы password (пароль) и textarea (текстовая область). Окно password похоже на окно text (текстовый тип, который устанавливается по умолчанию и не нуждается в именовании), однако при наборе текста символы не отображаются на экране. Область textarea тоже близка к типу по умолчанию, однако она может содержать несколько строк.

Для отображения длинных списков вариантов, из которых должен быть сделан выбор, используются теги . Такие списки часто представляются в виде выпадающего меню. Если задан параметр multiple (множественный), то их можно сравнить с флажками, если же он не задан — с переключателями.

Наконец, есть способы обозначить начальные значения (или значения по умолчанию), которые пользователь может менять. Например, если в области text задано поле value, содержимое отображается таким образом, чтобы пользователь мог его редактировать или стирать.

CSS — каскадные таблицы стилей

Изначальной целью HTML было определение именно структуры документа, а вовсе не его внешнего вида. Например, строка <1л1>Фотографии Натальи

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

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

Альтернативным и гораздо более удобным способом является использование таблиц стилей. Таблицы стилей в текстовых редакторах позволяют авторам ассоциировать текст с логическим, а не с физическим стилем, например «первый абзац» вместо «курсива». Внешний вид каждого стиля определен отдельно. Таким образом, если автор решит изменить шрифт первого абзаца с синего курсива кеглем 14 пт на розовый жирный кеглем 18 пт, потребуется изменить лишь одно определение, а не править весь документ.

CSS (Cascading Sryle Sheets — каскадные таблицы стилей) ввели таблицы стилей во Всемирную паутину с появлением HTML 4, однако они стали широко использоваться и поддерживаться в браузерах только в 2000 году. CSS определяет простой язык для описания правил, которым подчиняется внешний вид размеченного тегами контента. Давайте разберем пример. Предположим, что AWI хочет шикарные вебстраницы, текст на которых будет набран темно-синим цветом, шрифтом Arial на кремовом фоне, кегль заголовков первого уровня на 100 % больше, чем основной текст, а второго уровня — на 50 %. CSS определяет эти правила в листинге 7.6.

Листинг 7.6. Пример CSS

Как вы видите, определения стилей могут быть компактными. Каждая строка указывает элемент, к которому она относится, и задает значения свойств. Свойства элемента применяются по умолчанию ко всем элементам, которые содержатся в HTML. Таким образом, body задает стиль абзацев текста в теле документа. Существуют также удобные условные обозначения названий цветов (например, red — красный). Любые параметры стилей, которые не определены, заполняются браузером по умолчанию.

Такое поведение делает определения таблицы стилей факультативными; страница будет адекватно отображаться и без них.

Таблицы стилей можно поместить в файл HTML (например, используя тег

Перейти на страницу:

Все книги серии Классика computer science

Компьютерные сети. 5-е издание
Компьютерные сети. 5-е издание

Перед вами — очередное, пятое издание самой авторитетной книги по современным сетевым технологиям, написанной признанным экспертом в этой области Эндрю Таненбаумом в соавторстве с профессором Вашингтонского университета Дэвидом Уэзероллом. Первая версия этого классического труда появилась на свет в далеком 1980 году, и с тех пор каждое издание книги неизменно становилось бестселлером и использовалось в качестве базового учебника в ведущих технических вузах. В книге последовательно изложены основные концепции, определяющие современное состояние и тенденции развития компьютерных сетей. Авторы подробнейшим образом объясняют устройство и принципы работы аппаратного и программного обеспечения, рассматривают все аспекты и уровни организации сетей — от физического до уровня прикладных программ. Изложение теоретических принципов дополняется яркими, показательными примерами функционирования Интернета и компьютерных сетей различного типа. Пятое издание полностью переработано с учетом изменений, происшедших в сфере сетевых технологий за последние годы и, в частности, освещает такие аспекты, как беспроводные сети стандарта 802.12 и 802.16, сети 3G, технология RFID, инфраструктура доставки контента CDN, пиринговые сети, потоковое вещание, интернет-телефония и многое другое.

А. Гребенькова , Джеймс Уэзеролл

Технические науки

Похожие книги

102 способа хищения электроэнергии
102 способа хищения электроэнергии

Рассмотрена проблема хищений электроэнергии и снижения коммерческих потерь в электрических сетях потребителей. Приведены законодательно–правовые основы для привлечения к ответственности виновных в хищении электроэнергии. Изложены вопросы определения расчетных параметров средств учета электроэнергии, показаны схемы подключения счетчиков электрической энергии. Описаны расчетные и технологические способы хищения электроэнергии. Обсуждаются организационные и технические мероприятия по обнаружению, предотвращению и устранению хищений.Для работников энергоснабжающих организаций и инспекторского состава органов Ростехнадзора. Материалы книги могут быть использованы руководителями и специалистами энергослужб предприятий (организаций) для правильного определения расчетных параметров средств учета и потерь электроэнергии в электрических сетях.Если потенциальные расхитители электроэнергии надеются найти в книге «полезные советы», они должны отдавать себе отчет, что контролирующие структуры информированы в не меньшей степени и, следовательно, вооружены для эффективной борьбы с противоправной деятельностью.Настоящая книга является переработанным и дополненным изданием выпущенной в 2005 г. книги «101 способ хищения электроэнергии».

Валентин Викторович Красник

Технические науки / Образование и наука
Электроника для начинающих (2-е издание)
Электроника для начинающих (2-е издание)

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

Чарльз Платт

Радиоэлектроника / Технические науки
100 великих чудес инженерной мысли
100 великих чудес инженерной мысли

За два последних столетия научно-технический прогресс совершил ошеломляющий рывок. На что ранее человечество затрачивало века, теперь уходят десятилетия или всего лишь годы. При таких темпах развития науки и техники сегодня удивить мир чем-то особенным очень трудно. Но в прежние времена появление нового творения инженерной мысли зачастую означало преодоление очередного рубежа, решение той или иной крайне актуальной задачи. Человечество «брало очередную высоту», и эта «высота» служила отправной точкой для новых свершений. Довольно много сооружений и изделий, даже утративших утилитарное значение, тем не менее остались в памяти людей как чудеса науки и техники. Новая книга серии «Популярная коллекция «100 великих» рассказывает о чудесах инженерной мысли разных стран и эпох: от изобретений и построек Древнего Востока и Античности до небоскребов в сегодняшних странах Юго-Восточной и Восточной Азии.

Андрей Юрьевич Низовский

История / Технические науки / Образование и наука