WWW.DISSERS.RU

БЕСПЛАТНАЯ ЭЛЕКТРОННАЯ БИБЛИОТЕКА

   Добро пожаловать!

Pages:     | 1 |   ...   | 5 | 6 || 8 |

«Андрей Робачевский Операционная система Рекомендовано Министерством общего и профессионального образования Российской Федерации в качестве учебного пособия для студентов высших учебных заведений ...»

-- [ Страница 7 ] --

Рассмотрим теперь процесс возникновения SWS. Предположим, что от правитель вынужден передать сегмент размером 50 октетов (например, ес ли приложение указало флаг PSH). Таким образом, он отправляет 50 бай тов, и вслед за этим следующий сегмент, размером 150 октетов (поскольку размер доступного окна равен 200). Через некоторое время адресат полу чит 50 байтов, обработает их и подтвердит получение, не изменяя значе ния предлагаемого окна (1000 октетов). Однако теперь при вычислении доступного окна, отправитель обнаружит, что не подтверждены 950 бай тов, и, таким образом, его окно равняется всего 50 октетам. В результате отправитель вновь вынужден будет передать всего 50 байтов, хотя прило жение этого уже не требует.

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

Происхождение сегментов малого размера очевидно: периодически у от правителя возникает необходимость разделить доступное окно на несколь ко мелких сегментов. При непрерывной передаче больших объемов дан ных такие ситуации будут время от времени возникать, оставляя неизгла www.books-shop.com Протоколы транспортного уровня след на характере транзакций. В результате это может привести к "засорению" сети множеством мелких пакетов в одну сторону и множест вом подтверждений в другую.

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

1. Принимающая сторона не должна анонсировать маленькие окна. Го воря более конкретно, адресат не должен анонсировать размер окна, www.books-shop.com 416 Глава 6. сети в операционной системе UNIX больший текущего (который скорее всего равен 0), пока последний не может быть увеличен либо на размер максимального сегмента (Maximum Segment Size, MSS), либо на 1/2 размера буфера приема, в зависимости от того, какое значение окажется меньшим.

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

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

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

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

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

Алгоритм, направленный на избежание подобной ситуации, получил на звание медленного старта (slow start). Основная идея, лежащая в основе этого алгоритма, заключается в том, что на начальном этапе передачи сег менты должны отправляться со скоростью, пропорциональной скорости получения Реализация этого алгоритма предусматривает использование дополнитель ного к рассмотренным ранее окна отправителя — окна переполнения (congestion window). При установлении связи с адресатом значение этого окна устанавливается равным одному сегменту (значению MSS, анонсированному адресатом, или некоторому значению по умолчанию, www.books-shop.com Протоколы транспортного уровня обычно 536 или 512 байтов). При вычислении доступного окна отправи тель использует меньшее из предлагаемого окна и окна переполнения.

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

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

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

Устранение затора Переполнение, или затор, может возникнуть в сети по многим причинам.

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

Алгоритмы, позволяющие избежать заторов, основываются на предполо жении, что потеря данных, вызванная ошибками передачи по физической среде, пренебрежимо мала (гораздо меньше 1%). Следовательно, потеря вывести формулу изменения размера окна, предполагая, что время передачи данных от отправителя к получателю и обратно (Round Trip Time, гораздо больше времени пе редачи сегмента отправителем. Здесь параметр sz равен размеру сегмента (например, cwndo = sz = cwndo + = = = www.books-shop.com Глава 6. в операционной UNIX данных свидетельствует о заторе, произошедшем где то на пути следова ния пакета. В свою очередь, о потере данных отправитель может судить по двум событиям: значительной паузе в получении подтверждения или полу чении дубликата(ов) подтверждения.

Хотя устранение затора и медленный старт являются независимыми меха низмами, каждый из которых имеет свою цель, обычно они реализуются совместно. Для их работы необходимо два дополнительных параметра вир туального окно переполнения cwnd и порог медленного старта ssthresh. Работа комбинированного алгоритма определяется следующим правилам:

1. Начальные значения cwnd и ssthresh инициализируются равными размеру одного сегмента и 65535 байтов соответственно.

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

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

4. Когда отправитель получает подтверждение, он увеличивает размер cwnd, однако новый размер зависит от того, выполняет ли модуль медленный старт или устранение затора.

Если значение cwnd меньше или равно ssthresh, то TCP находится в фа зе медленного старта, в противном случае производится устранение затора.

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

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

Поскольку скорость передачи определяется текущим окном, половина размера окна, со храненная в ssthresh, определяет 1/2 скорости, при которой произошел затор.

www.books-shop.com Протоколы уровня нового значения cwnd производится по следующей формуле при каждом подтверждении = + Таким образом, формула дает зависимость роста размера окна, при кото рой максимальная скорость приращения составит не более одного сегмен та за время передачи данных туда и обратно (Round Trip Time, неза висимо от того, сколько подтверждений было получено. Это утверждение легко доказать. Допустим, в какой то момент времени размер окна состав лял Тогда отправитель может передать максимум сегмен тов размером sz, на которые он получит такое же число подтверждений.

Можно показать, что cwndn+i cwndn + = + sz На рис. 6.16 показан рост окна переполнения при медленном старте и по следующем устранении затора. Заметим, что переход в фазу устранения затора происходит при превышении размером окна порогового значения ssthresh.

Рис. 6,16. Рост окна переполне ния при медленном старте и устра нении затора Повторная передача До сих пор рассматривалось получение дублированных подтверждений как свидетельство потери сегментов и затора в сети. Однако согласно RFC "Requirements for Internet Hosts — Communication Layers", модуль TCP Предполагается, что получатель подтверждает каждый сегмент. На самом деле это не так, и в этом случае приращение производится фактически на число подтвержденных сегментов.

piracy@books-shop.com 420 Глава 6. сети в операционной системе UNIX может отправить немедленное подтверждение при получении неупорядо ченных сегментов. Цель такого подтверждения — уведомить отправителя, что был получен неупорядоченный сегмент, и указать порядковый номер ожидаемых данных. Поскольку ожидаемый порядковый номер остался прежним (получение неупорядоченного сегмента не изменит его значе ние), данное подтверждение может явиться дубликатом уже отправленного ранее.

Таким образом, получение дублированных подтверждений может быть вы звано двумя причинами: потерей сегмента, как следствием затора в сети, и получением неупорядоченного сегмента. Чтобы установить истинную при чину, модуль TCP ждет получения еще нескольких дублированных под тверждений. Если причина в получении неупорядоченного сегмента, вы званном буферизацией на промежуточных шлюзах или различными путя ми передачи датаграмм, то, вероятнее всего, вскоре ожидаемый сегмент будет получен и порядок будет восстановлен, что выразится в получении нового (уже не дубликата) подтверждения. Если получено три или более дубликатов, следует полагать, что произошла потеря данных. В этом слу чае отправитель совершает повторную передачу утраченного сегмента. Эта процедура получила название быстрой повторной передани (fast retransmit).

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

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

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

Несмотря на то что взаимодействие затрагивает передачу данных по сети, www.books-shop.com Программные интерфейсы приведенная программа мало отличается от примера, рассмотренного в разделе "Межпроцессное взаимодействие в BSD UNIX. главы 3.

Логика приложения сохранена — клиент отправляет серверу сообщение, сервер передает его обратно, а клиент, в свою очередь, выводит получен ное сообщение на экран. Наиболее существенным отличием является коммуникационный домен сокетов — в данном случае AF_INET. Соответ ственно изменилась и схема адресации коммуникационного узла. Соглас но схеме адресации TCP/IP, коммуникационный узел однозначно иденти фицируется двумя значениями: адресом хоста (IP адрес) и адресом про цесса (адрес порта). Это отражает и структура которая явля ется конкретным видом общей структуры адреса сокета sockaddr. Струк тура sockaddr_in имеет следующий вид:

struct { short u_short Номер порта struct IP адрес хоста char Адрес порта должен быть предварительно оговорен между клиентом и сер вером.

В заключение, прежде чем перейти непосредственно к текстам программы, заметим, что интерфейс сокетов также поддерживается и в UNIX System V, наряду с другим программным интерфейсом — ТЫ, который будет рас смотрен в следующем разделе.

Приведенный пример в качестве транспортного протокола использует TCP. Это значит, что перед передачей прикладных данных клиент должен установить соединение с сервером. Эта схема, приведенная на рис. 6.17, несколько отличается от рассмотренной в разделе "Межпроцессное взаи модействие в BSD UNIX. Сокеты", где передача данных осуществлялась без предварительного установления связи и в данном случае соответство вала бы использованию протокола UDP.

В соответствии с этой схемой сервер производит связывание с портом, номер которого предполагается известным для клиентов и сооб щает о готовности приема запросов При получении запроса он с помощью функции accept(2) создает новый сокет, который и обслуживает обмен данными между клиентом и сервером. Для того чтобы сервер мог продолжать обрабатывать поступающие запросы, он порождает отдельный процесс на каждый поступивший запрос. Дочерний процесс, в свою оче редь, принимает сообщения от клиента и передает их обратно Клиент не выполняет связывания, поскольку ему безразлично, какой адрес будет иметь его коммуникационный узел. Эту операцию выполняет систе www.books-shop.com сети в операционной UNIX 422 Глава 6.

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

Рис. 6.17. Схема установления связи и передачи данных между клиентом и сервером В программе используются несколько функций, которые не рассматрива лись. Эти функции значительно облегчают жизнь программисту, выпол няя, например, такие действия, как трансляцию доменного имени хоста в его IP адрес приведение в соответствие порядка следо вания байтов в структурах данных, который может различаться для хоста и сети а также преобразование IP адресов и их составных частей в соответствии с привычной "человеческой" нотацией, например Мы не будем подробнее останавливаться на этих функци www.books-shop.com Программные интерфейсы ях, предоставляя читателю самостоятельно обратиться к соответствующим разделам электронного справочника Ниже приведены тексты программ сервера и клиента.

Сервер ftinclude linclude ftinclude /*Номер порта сервера, известный #define argv) int char { int s, ns;

int pid;

int nport;

struct sockaddr_in serv_addr, struct hostent char /*Преобразуем порядок следования байтов к сетевому nport = PORTNUM;

nport = /*Создадим сокет, использующий протокол SOCK_STREAM, { вызова } /*3ададим адрес коммуникационного = = = /*Свяжем сокет с этим sockaddr { вызова } сообщение с указанием адреса "Сервер /*Сервер готов принимать запросы на установление соединения.

Максимальное число запросов, ожидающих обработки 5. Как правило, www.books-shop.com 424 Глава 6. сети в операционной системе UNIX этого числа достаточно, чтобы успеть выполнить и породить дочерний { вызова } цикл получения запросов и их while(1) { int addrlen;

addrlen = /*Примем запрос. Новый сокет ns становится коммуникационным узлом созданного виртуального (struct sockaddr { вызова accept } информацию о "Клиент = /*Создадим процесс для работы с { вызова } { int nbytes;

int этот сокет нам не Он по прежнему используется для получения close /*Получим сообщение от клиента и передадим его while = recv(ns, buf, !=0) { buf, 0);

} exit(0) } этот сокет нам не нужен. Он используется дочерним процессом для обмена } www.books-shop.com интерфейсы Клиент ttinclude порта, который обслуживается idefine argv) char int { int s int int ;

struct sockaddr_in struct hostent char /*B качестве аргумента клиенту передается доменное имя хоста, на котором запущен сервер. Произведем трансляцию доменного имени в { вызова } = = /*Создадим сокет*/ { вызова } "Адрес /*Создадим виртуальный if (struct sockaddr { вызова } /*0тправим серверу сообщение и получим его buf, www.books-shop.com 426 Глава 6. в UNIX if (recv(s, buf, sizeof(buf), 0) <0) { вызова } полученное сообщение на от сервера:

close завершил работу } Программный интерфейс TLI При обсуждении реализации сетевой поддержки в BSD UNIX был рас смотрен программный интерфейс доступа к сетевым ресурсам, основан ный на В данном разделе описан интерфейс транспортного уровня (Transport Layer Interface, TLI), который обеспечивает взаимодействие прикладных программ с транспортными протоколами.

ТЫ был впервые представлен в UNIX System V Release 3.0 в 1986 году.

Этот программный интерфейс тесно связан с сетевой подсистемой UNIX, основанной на архитектуре STREAMS, изолируя от прикладной програм мы особенности сетевой архитектуры. Вместо того чтобы непосредственно пользоваться общими функциями STREAMS, рассмотренными в преды дущей главе, ТЫ позволяет использовать специальный набор вызовов, специально предназначенных для сетевых приложений. Для преобразова ния вызовов ТЫ в функции интерфейса STREAMS используется библио тека ТЫ, которая в большинстве систем UNIX имеет название libnsl.a или Схема использования функций ТЫ во многом сходна с рассмотренным интерфейсом сокетов и зависит от типа используемого протокола — с предварительным установлением соединения (например, TCP) или без него (например, UDP).

На рис. 6.18 и 6.19 представлены схемы использования функций ТЫ для транспортных протоколов с предварительным установлением соединения и без установления соединения. Можно отметить, что эти схемы очень похожи на те, с которыми мы уже встречались в разделе "Межпроцессное взаимодействие в BSD UNIX. главы 3 при обсуждении сокетов.

Некоторые различия отмечены ниже при описании функций ТЫ.

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

www.books-shop.com Программные интерфейсы Для определения адреса ТЫ предоставляет общую структуру данных netbuf, имеющую вид:

struct netbuf { unsigned int maxlen;

unsigned int len;

char } Рис. 6.18. Схема вызова функций TLI для протокола с предварительным установ лением соединения Поле buf указывает на буфер, в котором может передаваться адрес узла, maxlen определяет его размер, a len — количество данных в буфере, т. е.

размер адреса. Эта структура по своему назначению похожа на структуру sockaddr, которая является общим определением адреса коммуникацион ного узла для Далее рассматривается пример сетевого приложе www.books-shop.com 428 Глава 6. сети в операционной UNIX ния, основанного на ТЫ, где показано, как netbuf используется при пе редаче адреса для протоколов TCP/IP.

Рис. 6.19. Схема вызова функций TLI для протокола без предварительного установления соединения Структура netbuf используется в ТЫ для хранения не только адреса, но и другой информации — опций протокола и прикладных данных. Эта струк тура является составной частью более сложных структур данных, исполь зуемых при передаче параметров в функциях ТЫ. Для упрощения дина мического размещения этих структур библиотека ТЫ предоставляет две функции: для размещения структуры и для освобож дения памяти. Эти функции имеют следующий вид:

char fd, int int f i e l ds ) ;

int *ptr, int Аргумент struct_type определяет, для какой структуры данных выделя ется память. Он может принимать следующие значения:

www.books-shop.com Программные интерфейсы Значение поля struct_type Структура данных T_BIND struct t_bind T_CALL struct t_call T_DIS struct t_discon T_INFO struct t_info struct struct t_unitdata T_UDERROR struct t_uderr Co структурами, приведенными в таблице, мы познакомимся при обсуж дении функций ТЫ. Большинство из них включают несколько элементов Поскольку в некоторых случаях может отсутствовать необходи мость размещения всех элементов поле fields позволяет указать, какие конкретно буферы необходимо разместить для данной структуры:

Значение поля fields Размещаемые и инициализируемые поля Все необходимые поля T_ADDR Поле addr В структурах t_bind, t_call, t_unitdata, t_uderr Поле opt в структурах t_call, t_uderr, Поле udata в структурах t_call, t_unitdata, Отметим одну особенность. Фактический размер буфера и, соответствен но, структуры netbuf зависят от значения поля maxlen этой структуры. В свою очередь, этот параметр зависит от конкретного поставщика транс портных услуг — именно он определяет максимальный размер адреса, оп ций и прикладных данных. Чуть позже мы увидим, что эта информация ассоциирована с транспортным узлом и может быть получена после его создания с помощью функции Поэтому для определения фак тического размера размещаемых структур в функции необходим аргумент d, являющийся дескриптором транспортного узла, который воз вращается процессу функцией Перейдем к основным функциям ТЫ.

Как видно из рис. 6.18 и в качестве первого этапа создания коммуни кационного узла используется функция Как и системный вы зов она возвращает дескриптор, который в дальнейшем адресует узел в функциях ТЫ. Функция имеет вид:

int char int struct piracy@books-shop.com 430 Глава 6. сети в операционной UNIX Аргумент path является именем специального файла устройства, являю щегося поставщиком транспортных услуг, например, /dev/tcp или Аргумент of lags определяет флаги открытия файла и соответст вует аналогичному аргументу системного вызова ореп(2). Приложение мо жет получить информацию о поставщике транспортных услуг в структуре info, имеющей следующие поля:

addr Определяет максимальный размер адреса транспортного протоко ла. Значение 1 говорит, что размер не ограничен, 2 означает, что прикладная программа не имеет доступа к адресам протокола.

Протокол TCP устанавливает размер этого адреса (адрес порта) равным options Определяет размер опций для данного протокола. Значение свидетельствует, что размер не ограничен, 2 означает, что при кладная программа не имеет возможности устанавливать опции протокола.

Определяет максимальный размер пакета данных протокола (Transport Service Data Unit, TSDU). Нулевое значение означает, что протокол не поддерживает пакетную передачу (т. е. не сохраняет границы записей). Значение 1 свидетельствует, что размер не ог раничен, 2 означает, что передача обычных данных не поддержи вается. Поскольку протокол TCP обеспечивает передачу неструкту рированного потока данных, значение tsdu для него равно 0. На против, UDP поддерживает пакетную передачу.

Определяет максимальный размер пакета экстренных данных про токола (Expedited Transport Service Data Unit, ETSDU). Нулевое зна чение означает, что протокол не поддерживает пакетную передачу (т. е. не сохраняет границы записей). Значение 1 свидетельствует, что размер не ограничен, 2 означает, что передача экстренных данных не поддерживается. TCP обеспечивает такую поддержку, а UDP нет.

connect Некоторые протоколы допускают передачу прикладных данных вместе с запросом на соединение. Поле connect определяет мак симальный размер таких данных. Значение 1 свидетельствует, что размер не ограничен, 2 означает, что данная возможность не под держивается. И TCP и UDP не поддерживают этой возможности.

discon Определяет то же, что и connect, но при запросе на прекращение соединения. И TCP и UDP не поддерживают этой возможности.

servtype Определяет тип транспортных услуг, предоставляемых протоколом.

Значение означает передачу с предварительным установ лением соединения, T_COTS_ORD — упорядоченную передачу с предварительным установлением соединения, — передачу без предварительного установления соединения. Протокол TCP обеспечивает услугу T_COTS_ORD, a UDP — т CLTS.

www.books-shop.com Программные интерфейсы Прежде чем передача данных будет возможна, транспортному узлу должен быть присвоен адрес. Эта фаза называется операцией связывания и мы уже сталкивались с ней при разговоре о в главе 3 и при обсуждении сетевой поддержки в BSD UNIX ранее в этой главе. В рассмотренных слу чаях связывание выполнял вызов В ТЫ для этого служит функция имеющая вид:

int const struct t_bind *req, struct t_bind Аргумент fd адресует коммуникационный узел. Аргумент req позволяет программе явно указать требуемый адрес, а через аргумент ret возвраща ется значение, установленное протоколом.

Два последних аргумента описываются структурой t_bind, имеющей сле дующие поля:

struct addr Адрес unsigned Максимальное число запросов на установление связи, ко торые могут ожидать обработки. Имеет смысл только для протоколов с предварительным установлением соединения Рассмотрим три возможных формата аргумента req:

req == NULL Позволяет поставщику транспортных услуг самому вы брать подходящий адрес req != NULL Позволяет поставщику транспортных услуг самому == 0 брать подходящий адрес, но определяет максимальное число запросов на установление связи, которые могут ожидать обработки req ! = NULL Явно указывает требуемый адрес и максимальное число len > 0 запросов на установление связи, которые могут ожидать обработки Во всех случаях фактическое значение адреса возвращается в структуре ret. Даже если программа явно указала требуемый адрес, необходимо проверить, совпадает ли он с адресом, указанным в ret.

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

Функция имеет вид:

int fd, const struct t_call struct t_call Аргумент содержит информацию, необходимую поставщику транспортных услуг для создания виртуального канала. Формат этой ин формации описывается структурой t call, имеющей следующие поля:

www.books-shop.com 432 Глава 6. сети в операционной системе UNIX struct netbuf Адрес удаленного транспортного узла struct netbuf opt Требуемые опции протокола struct netbuf udata Прикладные данные, отправляемые вместе с управляю щей информацией (запрос на установление соединения или подтверждение) int sequence в данном случае не имеет смысла Через аргумент программе возвращается информация о виртуаль ном канале после его создания: адрес удаленного узла, опции и приклад ные данные, переданные удаленным узлом. Как уже отмечалось, ни TCP, ни UDP не позволяют передавать данные вместе с управляющей инфор мацией. Программа может установить значение rcvcall равным NULL, если информация о канале ее не интересует.

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

Для протоколов с предварительным установлением соединения програм ма сервер вызывает функцию блокируя свое выполнение до получения запроса на создание виртуального канала.

#include int fd, struct Информация, возвращаемая транспортным протоколом в аргументе call, содержит параметры, переданные удаленным узлом с помощью соответст вующего вызова его адрес, установленные опции протокола, а также, в ряде случаев, прикладные данные, переданные вместе с запро сом. Поле sequence аргумента call содержит уникальный идентификатор данного запроса.

Хотя t_listen(3N), несмотря на название, напоминает функцию accept(2), используемую для сокетов, сервер должен выполнить вызов другой функ ции — для того, чтобы фактически принять запрос и устано вить соединение. Функция имеет вид:

ftinclude int fd, int connfd, struct t_call Аргумент fd адресует транспортный узел, принявший запрос (тот же, что и для функции Аргумент connfd адресует транспортный узел, для которого будет установлено соединение с удаленным узлом. За созда ние нового транспортного узла отвечает сама программа (т. е. необходим явный вызов функции при этом fd может по прежнему ис пользоваться для обслуживания поступающих запросов.

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

www.books-shop.com Программные интерфейсы После возврата из функции t_accept(3N) между двумя узлами и удаленным узлом клиентом) образован виртуальный канал, готовый к пе редаче прикладных данных.

Для обмена прикладными данными после установления соединения ис пользуются две функции: для получения и t_snd(3N) для переда чи. Они имеют следующий вид:

ttinclude int t_rcv(int char *buf, unsigned nbytes, int int t_snd(int fildes, char *buf, unsigned nbytes, int flags);

Первые три аргумента соответствуют аналогичным аргументам системных вызовов и Аргумент flags функции t_snd(3N) может со держать следующие флаги:

T_EXPEDITED Указывает на отправление экстренных данных T_MORE Указывает, что данные составляют логическую запись, продолже ние которой будет передано последующими вызовами Напомним, что TCP обеспечивает неструктурированный поток и, следовательно, не поддерживает данной возможности Эту информацию принимающий узел получает с помощью t_rcv(3N) также через аргумент flags.

Для протоколов без предварительного установления соединения исполь зуются функции и для получения и передачи соответственно. Функции имеют следующий вид:

ttinclude int fildes, struct t_unitdata *unitdata, int * int fildes, struct t_unitdata Для передачи данных используется структура unitdata, имеющая сле дующие поля:

struct netbuf addr Адрес удаленного транспортного узла struct netbuf opt Опции протокола struct netbuf udata Прикладные данные Созданный транспортный узел может быть закрыт с помощью функции t_close(3N). Заметим, что при этом соединение, или виртуальный канал, с которым ассоциирован данный узел, в ряде случаев не будет закрыт.

Функция t_close(3N) имеет вид:

ttinclude int где f d определяет транспортный узел. Вызов этой функции приведет к ос вобождению ресурсов, связанных с транспортным узлом, а последующий www.books-shop.com 434 Глава 6. сети в системе UNIX системный вызов close(2) освободит и файловый дескриптор. Судьба вир туального канала (если таковой существует) зависит от того, является ли транспортный узел, адресующий данный канал, единственным. Если это так, соединение немедленно разрывается. В противном случае, например, когда несколько файловых дескрипторов адресуют один и тот же транс портный узел, виртуальный канал продолжает существовать.

Завершая разговор о программном интерфейсе ТЫ, необходимо упомянуть об обработке ошибок. Для большинства функций ТЫ свидетельством ошибки является получение 1 в качестве возвращаемого значения. На против, в случае нормального завершения эти функции возвращают 0. Как правило, при неудачном завершении функции ТЫ код ошибки сохраняет ся в переменной t_errno, подобно тому, как переменная errno хранит код ошибки системного вызова. Для вывода сообщения, расшифровываю щего причину ошибки, используется функция void char При вызове t_error(3N) после неудачного завершения какой либо функции ТЫ будет выведено сообщение errmsg, определенное разработчиком программы, за которым последует расшифровка ошибки, связанной с ко дом t_errno. Если значение t_errno равно TSYSERR, то расшифровка представляет собой стандартное сообщение о системной ошибке, связан ной с переменной errno.

В заключение в качестве иллюстрации программного интерфейса ТЫ при ведем пример приложения клиент сервер. Как и в предыдущих примерах, сервер принимает сообщения от клиента и отправляет их обратно. Клиент, в свою очередь, выводит полученное сообщение на экран. В качестве со общения, как и прежде, выступает жизнерадостное приветствие "Здравствуй, Сервер tinclude finclude iinclude /*Номер порта, известный ttdefine int char www.books-shop.com Программные транспортных узлов int tn, int pid, flags;

int nport;

транспортных узлов сервера и struct sockaddr_in struct struct struct t_call узел. В качестве поставщика транспортных услуг выберем модуль { вызова адрес транспортного узла — он должен быть известен клиенту */ nport = /*Приведем в соответствие порядок следования байтов для хоста и nport = = AF_INET;

= = = = = (char число запросов, обработки, установим равным = узел с (struct *)0) < 0) { вызова exit } "Адрес сервера:

/*Поскольку в структуре t call нам понадобится только буфер для хранения адреса клиента, разместим ее if = (struct t_alloc(tn, { вызова } = = = 0;

= 0;

www.books-shop.com 436 Глава 6. сети в операционной системе UNIX цикл получения и обработки { поступления запроса на установление (t_listen(s, call) <0) { вызова } информацию о клиенте, сделавшем clnt_addr = (struct транспортный узел для обслуживания = (struct t_info *) <0) { вызова } /*Пусть система сама свяжет его с подходящим if (struct t_bind (struct *)0) <0) { вызова } запрос и переведем его обслуживание на новый транспортный if ntn, call) <0) { вызова новый процесс для обслуживания запроса. При этом родительский процесс продолжает принимать запросы от { t вызова } { int nbytes;

этот транспортный узел уже не нужен, он используется родителем*/ while = buf, sizeof(buf), !=0) { t_snd(ntn, buf, ) t www.books-shop.com Программные интерфейсы } процесс: этот транспортный узел не нужен, он используется дочерним процессом для обмена данными с } } Клиент ttinclude ttinclude ttinclude ttinclude ttinclude argv) char int { int tn;

iht struct sockaddr_in struct hostent char struct t_call /*B качестве аргумента клиенту передается доменное имя хоста, на котором запущен сервер. Произведем трансляцию доменного имени в { вызова } транспортный узел. В качестве поставщика транспортных услуг выберем модуль { вызова } системе самостоятельно связать узел с подходящим (struct t_bind (struct t_bind *}0) < 0} { вызова exit } "Адрес клиента:

inet www.books-shop.com 438 Глава 6. сети в операционной системе UNIX /*Укажем адрес сервера, с которым мы будем = в соответствие порядок следования байтов для хоста и = /*Поскольку в структуре t_call нам понадобится только буфер для хранения адреса сервера, разместим ее if ( (call = (struct t_alloc(tn, { вызова } = = = (char *) = 0;

= 0;

соединение с call, (struct t_call *)0)== 1) { вызова } сообщение и получим ответ */ buf, if (t_rcv(tn, buf, <0) { вызова exit } полученное сообщение на от сервера:

завершил } В рассмотренном примере большая часть исходного текста посвящена соз данию транспортных узлов и установлению соединения, в то время как завершение сеанса связи представлено скупыми вызовами t_close(3N). На самом деле, вызов t_close(3N) приводит к немедленному разрыву соедине ния, запрещая дальнейшую передачу или прием данных. Однако вирту альный канал, обслуживаемый протоколом TCP, является полнодуплекс ным и, как было показано, TCP предусматривает односторонний разрыв связи, позволяя другой стороне продолжать передачу данных. Действиям, предписываемым TCP, больше соответствуют две функции и t_rcvrel(3N), которые обеспечивают прекращение связи (orderly release). Разумеется, эти рассуждения справедливы лишь для транспорт ного протокола, обеспечивающего передачу данных с предварительным установлением связи, каковым, в частности, является протокол TCP.

www.books-shop.com Программные Функции и t_rcvrel(3N) имеют вид:

ttinclude ;

t fd);

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

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

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

Таблица 6.6. События, связанные с коммуникационным узлом Событие Значение Узлом получено подтверждение создания соединения Узлом получен запрос на разрыв соединения Узлом получены данные Узлом получены экстренные данные Узлом получен запрос на установление соединения T_ORDREL Узлом получен запрос на корректное прекращение связи T_ERROR Свидетельствует о фатальной ошибке T_UDERR Свидетельствует об ошибке Если в рассматриваемом случае событием, связанным с ошибкой является это означает, что удаленный узел завершил передачу данных и более не нуждается в соединении. Если узел, получивший запрос на прекращение связи, не возражает против полного прекращения сеанса, piracy@books-shop.com 440 Глава 6. сети в операционной системе UNIX он вызывает функцию Впрочем, при необходимости, комму никационный узел может продолжить передачу данных. Единственное, от чего ему следует воздержаться, это от попытки получения данных, или, другими словами, от вызова поскольку в этом случае выполне ние процесса будет навсегда заблокировано, т. к. данные от удаленного узла поступать не будут.

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

обработку принятых if == T_LOOK == { получен запрос на корректное прекращение Мы согласны на завершение сеанса, поэтому также корректно exit t получения данных (t exit Программный интерфейс высокого уровня. Удаленный вызов процедур В предыдущих разделах рассматривался программный интерфейс доста точно низкого уровня — по существу программа взаимодействовала непо средственно с транспортным протоколом, самостоятельно реализуя неко торый протокол верхнего уровня при обмене данными. В приведенных примерах легко заметить, что значительная часть кода этих программ по священа созданию коммуникационных узлов, установлению и завершению связи.

С точки зрения разработчика программного обеспечения, более перспек тивным является подход, когда используется прикладной программный интерфейс более высокого уровня, изолирующий программу от специфики сетевого взаимодействия. В данном разделе мы рассмотрим один из таких подходов, на базе которого, в частности, разработана файловая система NFS, получивший название удаленный вызов процедур (Remote Procedure Call, www.books-shop.com Программные интерфейсы Использование подпрограмм в программе — традиционный способ струк турировать задачу, сделать ее более ясной. Наиболее часто используемые подпрограммы собираются в библиотеки, где могут использоваться раз личными программами. В данном случае речь идет о локальном (местном) вызове, т. е. и и вызываемый объекты работают в рамках одной программы на одном компьютере.

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

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

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

1. Программа клиент производит локальный вызов процедуры, называе мой заглушкой (stub). При этом клиенту "кажется", что, вызывая за глушку, он производит собственно вызов процедуры сервера. И дейст вительно, клиент передает заглушке необходимые параметры, а она возвращает результат. Однако дело обстоит не совсем так, как это себе представляет клиент. Задача заглушки — принять аргументы, предна значаемые удаленной процедуре, возможно, преобразовать их в некий стандартный формат и сформировать сетевой запрос. Упаковка аргу ментов и создание сетевого запроса называется сборкой (marshalling).

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

На удаленном хосте все происходит в обратном порядке. Заглушка сервера ожидает запрос и при получении извлекает параметры — ар гументы вызова процедуры. может включать www.books-shop.com 442 Глава 6. сети в операционной системе UNIX необходимые преобразования (например, изменения порядка распо ложения байтов).

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

5. После выполнения процедуры управление в заглушку сервера, передавая ей требуемые параметры. Как и заглушка заглушка сервера преобразует возвращенные процедурой формируя сетевое сообщение отклик, который передается по сети сис теме, от которой пришел запрос.

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

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

возможно, выполняя преобразования к стандартному виду (например, из меняя порядок следования байтов). Гораздо сложнее обстоит дело с ' Кроме прочего, благодаря такому подходу, достигается независимость компо распределенного приложения (клиента и сервера) не только от сетевой ции, но и от типа операционных систем, под управлением которых они и от языка программирования, на котором написаны сами компоненты. Скажем, может быть создан в виде программы на языке С, выполняющейся пол управлением в то в качестве клиента может выступать разработанная на языке Pascal, выполняющаяся в среде Windows NT www.books-shop.com Программные интерфейсы дачей указателей, когда параметр представляет собой адрес данных, а не их значение. Передача в запросе адреса лишена смысла, так как удаленная выполняется в совершенно другом адресном пространстве. Са мым простым решением, применяемым в RPC, является запрет клиентам передавать параметры иначе, как по значению, хотя это, безусловно на кладывает серьезные Связывание (binding) Прежде чем клиент сможет вызвать удаленную процедуру, необходимо связать его с удаленной системой, располагающей требуемым сервером.

Таким образом, задача связывания распадается на две:

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

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

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

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

www.books-shop.com 444 Глава 6. сети в операционной UNIX номер порта, либо перенаправляет запрос непосредственно серверу удаленной процедуры и после ее выполнения клиенту отклик.

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

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

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

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

Таким образом, выполнение удаленной процедуры можно характеризовать следующей семантикой:

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

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

Хотя бы раз. Процедура наверняка была выполнена один раз, но воз и больше. Для работы в такой ситуации www.books-shop.com Программные процедура должна обладать свойством Этим обладает многократное вы которой не вызывает кумулятивных изменений. Например, чтение файла а добавление текста в файл — нет.

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

Например, формат представления данных в RPC фирмы Sun Microsystems следующий:

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

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

Вызываемые процедуры Размер передаваемых аргументов и возвращаемого результата мень ше размера пакета — 8 Кбайт.

О Сервер обеспечивает работу с несколькими сотнями клиентов. По скольку при работе с протоколами TCP сервер вынужден поддержи вать соединение с каждым из активных клиентов, это занимает www.books-shop.com 446 Глава 6. сети в системе часть его ресурсов. Протокол в этом отношении яв ляется менее ресурсоемким С другой стороны, TCP обеспечивает эффективную работу приложений со следующими характеристиками:

Приложению требуется надежный протокол передачи Вызываемые процедуры Размер аргументов или возвращаемого результата превышает 8 Кбайт Выбор протокола обычно остается за клиентом, и система по разному ор ганизует формирование и передачу сообщений. Так, при использовании протокола TCP, для которого передаваемые данные представляют собой поток байтов, необходимо отделить сообщения друг от друга. Для этого, например, применяется протокол записей, описанный в Remote Procedure Call Protocol version 2", при котором в начале каждого сообщения помещается 32 разрядное целое чис ло, определяющее размер сообщения в байтах.

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

Если же отклик не получен, определенно сказать, что процедура выполне на не была, Как это работает?

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

www.books-shop.com Программные клиента и сервера. Единственное, что необходимо сделать после этого, — написать фактический код процедуры.

В качестве примера рассмотрим RPC фирмы Sun Microsystems.

Система состоит из трех основных частей:

rpcgen(l) — который на основании описания ин терфейса удаленной процедуры генерирует заглушки клиента и сер вера в виде программ на языке С.

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

Библиотека модулей, обеспечивающих работу системы в целом.

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

Для этого придется создать как минимум три файла: спецификацию ин терфейсов удаленных процедур (на языке описания интерфейса), собственно текст удаленных процедур и текст головной программы клиента main — (на языке С).

Компилятор на основании спецификации log.x создает три фай ла: текст заглушек клиента и сервера на языке С и и файл описаний используемый обеими заглушками.

Итак, рассмотрим исходные тексты программ.

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

program LOG_PROG { version LOG_VER ( RLOG (string) 1;

} = i;

} = Компилятор rpcgen(l) создает файл заголовков log.h, где, в частности, оп ределены процедуры:

www.books-shop.com 448 Глава 6. сети в операционной системе UNIX /* * Please do not edit this file.

* It was generated using rpcgen.

ttifndef ftdefine ftdefine RLOG long) extern int /*Внутренняя процедура — нам ее использовать не extern int /* */ Рассмотрим этот файл внимательно. Компилятор транслирует имя RLOG, определенное в файле описания интерфейса, в заменяя пропис ные символы на строчные и добавляя номер версии программы с подчер киванием. Тип возвращаемого значения изменился с на int Таково правило — RPC позволяет передавать и получать только адреса объявлен ных при описании интерфейса параметров. Это же правило касается и пе редаваемой в качестве аргумента строки. Хотя из файла это не сле дует, на самом деле в качестве аргумента функции также пере дается адрес строки.

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

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

log. с #include значение должно определяться как static int result;

int дескриптор int www.books-shop.com Программные интерфейсы result = файл журнала если он не в случае неудачи вернем код ошибки result == !, j ! 0 APPEND);

< 0! return = if != len!

result = else result 0;

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

client.c argc, char { CLIENT char*server, time t server = В случае неудачи — сообщим о невозможности установления связи с if ( r piracy@books-shop.com 450 Глава 6. Поддержка сети в операционной системе UNIX /*Выделим буфер для строки*/ mystring = (char *)malloc(100);

/*0пределим время события*/ bintime = time((time_t *)NULL);

clnttime = ctime(&bintime );

sprintf (mystring, "%s — Клиент запущен", clntime);

/*Передадим сообщение для журнала — время начала работы клиента.

В случае неудачи — сообщим об ошибке*/ if ((result = rlog_l(&mystring, cl)) == NULL) { fprintf(stderr, "error2\n");

clnt_perror(cl, server);

exit (3) ;

} /*B случае неудачи на удаленном компьютере сообщим об ошибке*/ if (*result !=0 ) fprintf(stderr, "Ошибка записи в журнал\п"!;

/"Освободим дескриптор*/ clnt_destroy(cl);

exit(0);

Заглушка клиента компилируется с модулем для получе исполняемой программы клиента.

о Заглушка сервера и компилируются для получе ния исполняемой программы сервера.

о log svc.e Теперь на некотором хосте server.nowhere.ru необходимо запустить сервер ный $ logger После чего при запуске клиента Hog на другой машине сервер добавит со ответствующую запись в файл журнала.

Схема работы RPC в этом случае приведена на рис. 6.20. Модули взаимо действуют следующим образом:

1. Когда запускается серверный процесс, он создает сокет и связы вает любой локальный порт с этим сокетом. Далее сервер вызывает библиотечную функцию для регистрации номеров программы и ее версии. Для этого функция к и передает требуемые значения. Сервер 1М) обыч но запускается при инициализации системы и связывается с рым общеизвестным портом. Теперь знает номер порта www.books-shop.com Программные интерфейсы для нашей программы и версии. Сервер же ожидает получения запро са. Заметим, что все описанные действия производятся заглушкой сер вера, созданной компилятором 2. Когда запускается программа первое, что она делает, — вызывает библиотечную функцию указывая ей адрес удаленной сис темы, номера программы и версии, а также транспортный протокол.

Функция направляет запрос к серверу удаленной системы server.nowhere.ru и получает номер удаленного порта для сервера журнала.

3. Клиент вызывает процедуру rlog_l определенную в заглушке ента, и передает заглушке. Та, в свою очередь, формирует запрос (преобразуя аргументы в формат XDR) в виде пакета и направляет его на удаленный порт, полученный от сервера Затем она некоторое время ожидает отклика и в случае неполучения повторно отправляет запрос. При благоприятных обстоя тельствах запрос принимается сервером logger (модулем заглушки сер вера). Заглушка определяет, какая именно функция была вызвана (по номеру процедуры), и вызывает функцию rlog_l модуля По сле возврата управления обратно в заглушку преобразует возвращенное функцией значение в формат XDR, и форми рует отклик также в виде пакета UDP. После получения отклика глушка клиента извлекает возвращенное значение, преобразует его и в головную программу клиента.

Рис. 6.20. Работа системы RPC www.books-shop.com Глава 6. в операционной UNIX Поддержка сети в BSD UNIX Перейдем теперь к обсуждению внутренней архитектуры сетевого в UNIX. Разговор начнем с ветви UNIX, в которой реализация TCP/IP появилась впервые — BSD UNIX.

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

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

Легко заметить, что представленные уровни соответствуют транспортному, сетевому уровням и уровню канала данных модели OSI.

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

Внутренняя структура сетевой подсистемы изолирована от непосредствен ного доступа прикладных процессов. Единым (и единственным) интер фейсом доступа к сетевым услугам является интерфейс сокетов, рассмот ренный в главе 3 в разделе "Межпроцессное взаимодействие в BSD UNIX.

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

Движение данных вниз (т. е. от верхних уровней к нижним) обычно ини циируется системными вызовами и может иметь синхронный характер.

Принимаемые данные из сети поступают в случайные моменты времени и передаются сетевым драйвером в очередь приема соответствующего прото www.books-shop.com сети в BSD UNIX кола. При этом функции модуля протокола и обработка данных не вызы ваются непосредственно сетевым драйвером. Вместо этого последний ус танавливает бит соответствующего программного прерывания, в контексте которого система позднее и запускает необходимые функции. Если данные предназначены протоколу верхнего уровня (транспортному), его функция обработки будет вызвана непосредственно модулем сетевого уровня. Если же сообщение предназначено другому хосту, и система выполняет функ ции шлюза, сообщение будет передано уровню сетевого интерфейса для последующей передачи.

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

Структуры данных Структура данных socket, описывающая сокет, представлена на рис. 6.21.

В этой структуре хранится информация о типе сокета его те кущем состоянии и используемом протоколе (so_proto).

Рис. Структуры данных сокета www.books-shop.com 454 Глава д. сети в операционной системе UNIX Сокет является коммуникационным узлом и обеспечивает буферизацию получаемых и отправляемых данных. Как только данные попадают в рас поряжение сокета в результате системного вызова (например, или сокет немедленно передает их модулю протокола для последую щего отправления. Данные передаются в виде связанного списка специ альных буферов mbuf, структура которых также показана на рис. 6.21. Мо дуль протокола может ожидать подтверждения получения отправленных данных или отложить их отправку. В обоих случаях сообщения остаются в буфере передачи сокета до момента окончательной отправки или получе ния подтверждения. Аналогично, данные, полученные из сети, в конечном итоге в приемной очереди сокета адресата, пока не будут извлечены оттуда системным вызовом (например, read(2) или Для избежания переполнения буфер (структура хранит параметр — значение верхней ватерлинии. Модуль коммуникационного протокола может использовать это значение для управления потоком дан ных. Например, модуль TCP устанавливает максимальное значение окна приема равным этому параметру.

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

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

Вид коммутатора протокола показан на рис. 6.22.

Рис. 6.22. Коммутатор прото кола www.books-shop.com сети в BSD UNIX Перед первым использованием модуля вызывается функция его инициали зации pr_init После этого система будет вызывать функции таймера модуля протокола pr_fasttimo каждые 200 миллисекунд и каждые 500 миллисекунд, если протокол определил эти функции. Например, модуль протокола TCP использует функции таймера для обработки тайм аутов при установлении связи и повторных передачах.

Функция pr_drain вызывается системой при недостатке свободной па мяти и позволяет модулю уничтожить некритичные сообщения для осво бождения места.

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

Одним из параметров этой функции является номер запроса, зависящий от произведенного системного вызова. Интерфейс взаимодействия сокета с прикладными процессами является стандартным интерфейсом системных вызовов и преобразует вызовы и т. д. в соответствующие запросы функции Некоторые из них при ведены в табл. 6.7.

Таблица 6.7. Запросы функции pr_usrreq() Системный вызов Значение Запрос PRU ABORT close(2) Прекратить обмен данными ACCEPT accept(2) Обработать запрос на установление связи PRU BIND bind(2) Связать сокет с адресом PRU CONNECT Установить связь PRU LISTEN listen(2) Разрешить обслуживание запросов send(2), Отправить данные PRU_SENSE fstat(2) Определить состояние сокета PRU SOCKADDR getsockname(2) Получить адрес локального сокета PRU PEERADDR Получить адрес удаленного сокета PRU CONTROL ioctl(2) Передать команду модулю протокола Функции pr_input и pr_output определяют интерфейс взаимодей ствия и служат для передачи данных между модулями соседних уровней. Аналогично для обмена управляющими командами между модулями протоколов используются функции pr_ctlinput и pr_ctloutput Цепочка взаимодействующих протоколов производит размещение и освобождение памяти при обмене сообщениями, которые пе редаются посредством рассмотренных структур mbuf: при передаче сообще ний от сети прикладному процессу за освобождение буферов mbuf отвечает модуль верхнего уровня и наоборот, при передаче сообщений в сеть память, занимаемая сообщением, освобождается на самом нижнем уровне.

www.books-shop.com 456 Глава 6. сети в операционной системе UNIX Поле pr_flags определяет некоторые характеристики протокола и режим его функционирования, которые в основном относятся к уровню сокетов.

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

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

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

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

Рис. 6.23. Сетевой интерфейс Решение об использовании того или иного сетевого интерфейса для пере дачи сообщения базируется на таблице маршрутизации и производится www.books-shop.com сети в BSD модулем сетевого уровня. Интерфейс может обслуживать протоколы раз личных коммуникационных доменов. Соответственно, один и тот же ин терфейс может иметь несколько адресов, определенных для каждого се мейства протоколов. Структуры, определяющие локальный и широкове щательный (broadcast) адреса интерфейса, а также сетевую маску, хранятся в виде связанного списка.

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

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

Таблица 6.8. Состояния интерфейса Флаг Значение Интерфейс доступен для использования IFF_BROADCAST Интерфейс поддерживает широковещательные адреса Интерфейс поддерживает групповые адреса Интерфейс обеспечивает возможность отладки IFF_LOOPBACK Программный внутренний интерфейс Интерфейс для канала точка точка Ресурсы интерфейса успешно размещены IFF_NOARP Интерфейс не использует протокол трансляции адреса Флаг IFF_UP свидетельствует о готовности интерфейса передавать сооб щения. Если сетевой интерфейс подключен к физической сети, поддержи вающей широковещательную адресацию (broadcast), например, Ethernet, для интерфейса будет установлен флаг IFF_BROADCAST и определен широ ковещательный адрес (поле структуры адресов для соответствующего коммуникационного домена). Если же интерфейс ис пользуется для канала точка точка, будет установлен флаг и определен адрес хоста (интерфейса), расположенного на противоположном конце (поле ifa_dstaddr). Заметим, что эти два флага являются взаимоисключающими, a и ifa_dstaddr являются различными именами одного и того же поля. Интерфейс уста навливает флаг IFF_RUNNING после размещения необходимых структур данных и отправления начального запроса на чтение устройству (напри мер, сетевому адаптеру), с которым он ассоциирован.

www.books-shop.com 458 Глава 6. сети операционной системе UNIX Состояние интерфейса и ряд других параметров можно просмотреть с по мощью команды $ inet netmask ffffffOO broadcast Легко заметить, что команда выводит значение следующих полей структу ры для интерфейса leO if_flags, if_mtu (Maximum Transmission Unit, MTU) определяющее максимальный размер пакета, ко торый может быть передан по физической сети, а также значения полей структуры адрес интерфейса inet маску netmask и широковещательный адрес broadcast (ifa_broadaddr).

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

$ in Name Mtu Net/Dest Address Opkts Oerrs Collis 823 127.0.0.0 127.0.0.1 168761 0 168761 О О leO 1500 194.85.160.0 1624636 1042 110166 1933 Маршрутизация Сетевая подсистема предназначена для работы в коммуникационной сре де, представляющей собой набор сетевых сегментов, связанных между со бой. Связь между отдельными сегментами достигается путем подключения их к хостам, имеющим несколько различных сетевых интерфейсов, как показано на рис. 6.24. Такие хосты при необходимости выполняют переда чу данных от одного сегмента к другому Для сетей пакетной коммутации, о которых идет речь, выполнение этой задачи непосредст венно связано с выбором маршрута прохождения пакетов данных (routing).

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

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

www.books-shop.com сети в BSD UNIX определения маршрута как для сетей с разделяемой средой переда чи (например, Ethernet), так и для сетей с каналами типа точка точка. На пример, для доставки пакета удаленному хосту, подключенному к сети первого типа, достаточно знать адрес этой сети, в то время как для кана лов точка точка необходимо явно задать адрес интерфейса противополож ного конца Рис. 6.24. Коммуникационная среда UNIX (internetwork) При определении маршрута модуль сетевого протокола (IP) сначала про сматривает элементы таблицы для хостов, а затем для сетей. Если оба по иска не дают результата, используется маршрут по умолчанию (если такой установлен), определенный как маршрут в сеть с адресом 0. Обычно ис пользуется первый найденный маршрут. Таким образом, порядок поиска обеспечивает приоритетность маршрутов к хостам по отношению к мар шрутам к сетям, что естественно, поскольку первые представлены более конкретными адресами.

Каждый элемент таблицы маршрутизации, показанный на рис. 6.25, со держит адрес получателя (это может быть адрес сети получателя или адрес Вспомним, что IP адрес состоит из двух частей — адреса сети и адреса хоста в этой сети.

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

piracy@books-shop.com 460 Глава 6. сети в операционной UNIX конкретного хоста). Это значение хранится в поле rt_dst. Следующее по ле, rt_gateway, определяет следующий шлюз, которому необходимо на править пакет, чтобы последний в конечном итоге достиг адресата. Поле rt_flags определяет тип маршрута (к хосту или к сети), а также его со стояние. В поле rt_use хранится число переданных по данному маршруту пакетов, a rt_refcnt определяет использование маршрута сетевыми про цессами (виртуальными каналами). Наконец, поле rt_ifp адресует сете вой интерфейс, которому необходимо направить пакет для дальнейшей передачи по данному маршруту.

Рис. 6.25. Элемент таблицы мар шрутизации Различают не только маршруты к хостам и сетям, но также маршруты пря мые (direct) и косвенные (indirect). Первое различие определяет критерий сравнения адреса получателя пакета с полем rt_dst элемента таблицы маршрутизации. Если маршрут к сети, то сравнивается только сетевая часть адреса, в противном случае требуется полное совпадение адресов.

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

www.books-shop.com в BSD UNIX Данный аспект проиллюстрирован на рис. 6.26. Здесь мы рассмотрели процесс передачи хосту, расположенному в удаленном се тевом сегменте Ethernet. Поскольку доставка предполагает ис пользование промежуточного шлюза, передача данных на канальном уров не требует соответствующей адресации: на первом "перегоне" в качестве адреса получателя используется шлюза, и только затем — фактического адресата.

Рис. 6.26. Инкапсуляция пакетов для косвенных маршрутов На то, что маршрут является косвенным, указывает флаг RTF_GATEWAY элемента таблицы маршрутов. В этом случае МАС адрес получателя при формировании кадра канального уровня, будет определяться исходя из се тевого адреса шлюза, хранящегося в поле Модуль протокола имеет возможность доступа к ин формации с помощью трех функций: rtalloc для получения маршрута, для его освобождения и rtredirect для обработки управ ляющих сообщений о перенаправлении маршрута REDIRECT).

Для определения соответствия между IP адресами интерфейсов и их ис пользуется протокол ARP (Address Resolution Protocol), позволяющий производить форми рование адреса кадра уровня канала данных.

www.books-shop.com Глава 6. сети в операционной системе UNIX Функция rtalloc позволяет модулю протокола определить маршрут к требуемому адресату. В результате модуль размещает структуру route, имеющую следующие поля:

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

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

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

Рис. 6.27. Пере направление мар шрутов В семействе протоколов TCP/IP для этих целей служит протокол Сообщения о перенаправлении маршрутов ICMP REDIRECT формируются IP модулем шлюза и инфор мируют IP модули соседних хостов (шлюзов) о существовании более выгодного маршрута к данному адресату.

www.books-shop.com сети в BSD Данная возможность может использоваться для упрощения процедуры формирования таблицы маршрутизации. Например, рабочие станции мо гут хранить только маршрут по умолчанию (в сеть 0), адресующий сосед ний шлюз. При передаче данных хостам той же сети, что и источник, шлюз будет информировать последний о перенаправлении маршрутов, по зволяя тем самым заполнить элементы таблицы.

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

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

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

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

Текущую таблицу маршрутизации можно увидеть, воспользовавшись ко мандой $ Routing Table:

Destination Gateway Flags Ref Use Interface 127 0 3 default 0 Первая запись таблицы показывает маршрут для псевдохоста (localhost) логической сети операционной системы. Следующий маршрут адресует непосредственно подключенную к интерфейсу (его адрес 194.85.160.50) сеть (194.85.160.0). Наконец, последняя запись определяет маршрут по умолчанию, направляя все пакеты, адресованные получателям "внешнего мира", для которых наш хост не знает конкретных маршрутов, на шлюз с адресом который обладает большей информацией о возмож ных маршрутах.

www.books-shop.com 464 Глава 6. сети в операционной UNIX Реализация TCP/IP Прежде чем перейти к описанию функционирования модулей протоколов TCP/IP, рассмотрим еще одну структуру данных, называемую управляющим блоком протокола (Protocol Control Block, PCB), который в случае TCP/IP называется Internet PCB, и представлен структурой inpcb, определенной в файле Вид структуры inpcb показан на рис. 6.28.

Рис. 6.28. Структуры данных протоколов TCP/IP Эта структура создается для каждого активного сокета TCP или UDP и содержит информацию, необходимую для текущих транзакций протокола, такую как IP адреса источника и получателя (inp_laddr и номера портов и www.books-shop.com сети в BSD UNIX ции TCP создает дополнительный управляющий блок, где хранятся данные, необходимые для работы этого протокола (такие как по рядковые номера, номера подтверждений и т. д.) Управляющие блоки размещаются в виде связанного списка, отдельного для TCP и UDP. Модули протокола имеют в своем распоряжении набор функций для создания, поиска и удаления управляющего блока. Модуль IP демультиплексирует сообщения на основании номера протокола, ука занного в заголовке а протокол транспортного уровня, в свою очередь, производит поиск требуемого управляющего блока для доставки данных протоколам более высокого уровня (приложений).

Перейдем теперь к описанию взаимодействия рассмотренных модулей в сетевой подсистеме BSD UNIX (рис. 6.29).

Рис. 6.29. Сетевая подсистема BSD UNIX www.books-shop.com 466 Глава 6. сети в операционной системе UNIX Модуль IP Сетевой интерфейс получает пакеты данных из сети и передает их соот ветствующему модулю сетевого уровня на основании информации, содер жащейся в заголовке кадра уровня канала. В данном разделе мы не будем рассматривать поддержку различных сетевых протоколов, а остановимся только на взаимодействии с протоколом IP. В этом случае полученные па кеты помещаются в очередь приема модуля IP. После этого с помощью программного прерывания вызывается процедура ip_input которая поочередно извлекает пакеты из очереди и обрабатывает их. После обра ботки на основании информации заголовка данные либо передаются протоколу транспортного уровня, либо уничтожаются, если в данных обнаружена ошибка, либо передаются другому интерфейсу для по следующей отправки фактическому адресату. В последнем случае система выполняет роль шлюза.

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

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

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

Возможность передачи на другой интерфейс определяется установкой соответствующего флага при конфигурации сетевой подсистемы (модуля IP). Например, в операционной системе SCO UNIX за это отвечает настраиваемый параметр ядра www.books-shop.com сети в BSD UNIX Производится проверка адреса получателя. Если адрес не принадлежит адресному пространству сетей класса А, В или С, такие данные не могут быть Определяется маршрут передачи датаграммы.

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

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

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

Таблица 6.9. Сообщения ICMP Сообщение Причина DESTINATION UNREACHABLE Невозможно доставить Причин может быть несколько:

Отсутствует маршрут к сети 2. Отсутствует маршрут к хосту 3. Для передачи необходима фрагментация, но в заголовке установлен флаг (Don't Fragment) SOURCE QUENCH Переполнение сети. Шлюз передает это сообще ние, запрашивая отправителя на уменьшение ско рости передачи данных TIME EXCEEDED Тайм аут. Причины могут быть две:

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

через определенный промежуток времени полу чены не все фрагменты датаграммы При вызове функции ей передается которую необходимо отправить, указатель на маршрут (структура route, хранящая ся в управляющем блоке), а также флаги (например, указание не исполь зовать таблицы). Передача маршрута не является обя Адреса сетей класса D — групповые (multicast) адреса — используются для создания специ альных наложенных сетей (Multicast backbone, предназначенных для таких при ложений, как видео, аудиоконференции и т. п. Обработка таких датаграмм выполняется, как правило, специальными демонами отдельно от стандартных функций шлюзования.

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

www.books-shop.com 468 Глава 6. Поддержка в операционной системе UNIX зательной. Если функции не передан указатель на маршрут, будет исполь зован маршрут из таблицы маршрутизации. В противном случае будет произведена проверка переданного маршрута, и при необходимости его значение будет обновлено для последующего использования.

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

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

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

Далее определяется получатель пакета. Для этого на основании адресов и номеров портов отправителя и получателя производится поиск соответст вующего управляющего блока В системе могут существовать несколько управляющих блоков с одинаковым номером локального порта, но с различными адресами и/или номерами портов отправителя. В этом случае выбирается блок, для которого найдено лучшее совпадение по всем четырем параметрам. Конечно, лучшим является точное совпадение, но если такового не найдено, будет выбран блок с совпадающим номером локаль ного порта, но неуказанным адресом и/или номером порта отправителя. Та ким образом, управляющий блок, у которого не указаны часть или все четы ре параметра, является получателем всех пакетов, для которых не найдено лучшего Если управляющий блок найден, данные и адрес отправителя помещаются в буфер приема сокета, связанного с управляющим блоком. В противном случае генерируется сообщение PORT UNREACHABLE.

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

Возможность создания таких получателей "по умолчанию" используется в сетевом супер сервере inetd, который прослушивает все запросы и при необходимости запускает требуе мый сервис (например FTP или Telnet). Это позволяет избежать запуска серверов без не обходимости и тем самым сократить потребление ресурсов.

www.books-shop.com сети в BSD UNIX Передача данных от приложения инициируется системным вызовом sendto(2), который на уровне сокета преобразуется в вызов функции с запросом PRU_SEND. Если передача инициирована сис темным вызовом то вместе с данными передается адрес получате ля. Если же данные были переданы с помощью системного вызова send(2), то адрес получателя определяется из управляющего блока, где он был со хранен предшествующим вызовом Фактическая передача осуществляется функцией которая формирует заголовок пакета, устанавливает значения его полей и вычисля ет контрольную сумму. После этого производится вызов уже рассмотрен ной ранее функции ip_output Как следует из предшествующего описания TCP, этот транспортный про токол обеспечивает гораздо более высокое качество передачи, чем UDP.

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

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

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

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

piracy@books-shop.com 470 Глава 6. сети в операционной UNIX Второй таймер — это (таймер сохранения). Этот таймер обеспе чивает защиту от потери управляющих сообщений, содержащих значения окна. В случае, если отправитель готов передать данные, но анонси рованное получателем окно слишком мало (равно нулю или меньше опреде ленного значения), и отсутствуют неподтвержденные данные (т. е. таймер по вторной передачи не включен), включается таймер сохранения. Если таймер срабатывает (его значение становится равным нулю), а обновленное значение так и не получено, отправитель передает максимально допустимый объем данных, определяемый текущим окном. Если же в этом случае значение те кущего окна равно нулю (нулевое окно), то передается пробный сегмент (window probe), содержащий один октет данных, и таймер запускается снова.

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

Следующий таймер, который мы рассмотрим, — Этот таймер предназначен для мониторинга каналов, по которым не передают ся данные, и которые возможно в действительности прекратили свое су ществование, например, из за аварийного останова одной из систем. Если за определенный промежуток времени данные по каналу переданы не были, модуль TCP отправляет пробный сегмент keepalive, ожидая в ответ либо подтверждения (это означает, что задержка в передаче данных временная), либо сообщения сброса канала (RST). Если получен сегмент RST, канал будет закрыт. Если после нескольких попыток, не будет получен отклик, канал будет уничтожен.

Последний таймер из рассматриваемых, это (2MSL — двойное максимальное время жизни сегмента в сети). Модуль TCP запускает этот таймер, когда производится завершение связи, и уже отправлено подтвер ждение полученному сегменту FIN. При этом отправитель не знает, получе но ли его подтверждение. Поэтому он некоторое время ждет возможного повторного получения сегмента FIN, чтобы в свою очередь повторить под тверждение. Таймер запускается при переходе коммуникационного узла ка нала в состояние TIME WAIT, и после его срабатывания соответствующий управляющий блок удаляется. Заметим, что это ожидание не блокирует про цесс, выполнивший системный вызов close(2) сокета, отвечающего за дан ный канал. Другими словами, управляющий блок может существовать еще некоторое время после закрытия дескриптора сокета.

Поддержка сети в UNIX System V Многие из аспектов реализации поддержки сети в BSD UNIX справедли вы и для архитектуры сетевых протоколов UNIX System V. Однако сам ме www.books-shop.com сети в UNIX System V ханизм обеспечения взаимодействия модулей существенно отличается. Для поддержки сети в UNIX System V используется подсистема STREAMS, рассмотренная в главе 5.

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

Обмен данными между модулями STREAMS также соответствует характеру взаимодействия отдельных протоколов: данные передаются в виде сообще ний, а каждый модуль выполняет требуемую их обработку. На рис. 6.30 при ведена схема реализации протоколов TCP/IP в UNIX System V. Используя терминологию предыдущей главы, можно отметить, что модуль IP является гибридным мультиплексором, позволяя обслуживать несколько потоков, приходящих от драйверов сетевых адаптеров (в данном случае Ethernet и FDDI), и несколько потоков к модулям транспортных протоколов (TCP и UDP), а модули TCP и UDP — верхними мультиплексорами, обслуживаю щими прикладные программы, такие как сервер маршрутизации сервер удаленного терминального доступа сервер FTP a также программы клиенты пользователей (например Рис. 6.30. Реализация протоколов TCP/IP на основе архитектуры STREAMS Анализ программного обеспечения сетевой поддержки показывает, что как правило сетевые и транспортные протоколы, составляющие базовый стек TCP/IP, поставляются одним производителем, в то время как поддержка www.books-shop.com Глава 6. сети в операционной системе UNIX уровней сетевого интерфейса и приложений может осуществляться продук тами различных разработчиков. Соответственно, можно выделить два ос новных интерфейса взаимодействия, которых позволяет обеспечить совместную работу различных компонентов программного обес печения. Первый интерфейс определяет взаимодействие транспортного уровня и уровня приложений и называется интерфейсом поставщика транс портных услуг (Transport Provider Interface, TPI). Второй интерфейс устанав ливает правила и формат сообщений, передаваемых между сетевым уровнем и уровнем сетевого интерфейса, и называется интерфейсом поставщика услуг канала данных (Data Link Provider Interface, Вообще говоря, сетевая архитектура, основанная на архитектуре STREAMS, позволяет обеспечить поддержку любого стека протоколов, со ответствующего модели OSI. Поэтому выражаясь более точно, перечис ленные интерфейсы определяют взаимодействие транспортного уровня и уровня сеанса, и уровня канала и сетевого уровня, соответственно. Эти рассуждения проиллюстрированы на рис.

TCP/IP OSI Уровень приложений Уровень процесс представления telnetd, talk Уровень TPI * Транспортный Модули TCP, уровень Т Сетевой Модуль IP уровень Л Т Драйвер сетевого канала данных Рис. 6.31. Интерфейсы взаи FDDI Физический модействия модулей протоко лов Интерфейс TPI TPI представляет собой интерфейс предоставления услуг транспортного уровня OSI модели как с предварительным установлением соединения (connection mode), так и без установления соединения (connectionless mode). Стандартизация этого интерфейса позволяет изолировать особен ности реализации транспортного уровня от потребителя этих услуг и, тем самым, предоставить возможность разработки программного обеспечения, независимо от конкретного протокола и услуг им предоставляемых.

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

www.books-shop.com сети в UNIX System V TPI определяет набор и формат сообщений, с помощью которых протоко лы верхнего уровня взаимодействуют с модулем транспортного протокола.

Таким образом, TPI является интерфейсом между поставщиком транс портных услуг (transport provider) и пользователем этих услуг (transport user).

Эти сообщения определяют транспортные примитивы (transport primitive), или команды, и могут иметь следующий формат:

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

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

Сообщение состоит из одного или более блоков в которых передаются данные прикладной программы.

Таблица 6.10. Основные управляющие сообщения TPI Транспортный Тип со Значение примитив общения т BIND REQ м PROTO Запрос на связывание.

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

Блок содержит следующие поля:

Тип — ADDR_length Размер адреса протокола f set Смещение адреса в блоке Максимальное число запросов, ожи дающих обслуживания T_BIND_ACK Подтверждение получения запроса на связывание.

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

Блок M_PROTO содержит следующие поля:

Тип примитива — T_BIND_ACK Размер адреса протокола f set Смещение адреса в блоке Максимальное число запросов, ожидающих обслуживания www.books-shop.com 474 Глава 6. сети в операционной системе UNIX Таблица (продолжение) Транспортный Тип со Значение примитив общения Т UNBIND REQ M PROTO Запрос на уничтожение связывания.

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

Т CONN REQ M PROTO Запрос на установление связи.

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

Заметим, что протокол TCP не позволяет переда вать прикладные данные вместе с запросом. Блок содержит значение адреса получателя и опции, связанные с этим примитивом.

Блок содержит следующие поля:

Тип примитива — DEST_length Размер адреса протокола Смещение адреса получателя в бло ке Размер опций ОРТ offset опций в PROTO Т CONN M PROTO Индикация установления связи.

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

Блок содержит следующие поля:

Тип примитива — SRC_length Размер адреса протокола Смещение адреса отправителя в блоке OPT_length Размер опций OPT_offset Смещение опций в блоке Идентификатор соединения www.books-shop.com сети в UNIX System V Таблица 6.10 (продолжение) Тип со Значение примитив общения Ответ на запрос на установление связи.

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

Блок содержит следующие поля:

PRIM_type Тип примитива — Указатель на очередь потока, который должен быть использован в качестве узла созданного соединения OPT_length Размер опций f set Смещение опций в блоке Идентификатор соединения T_CONN_CON Подтверждение установления связи.

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

Блок содержит следующие поля:

Тип примитива — T_CONN_CON RES_length Размер адреса протокола set Смещение адреса удаленного узла в блоке OPT_length Размер опций ОРТ offset Смещение опций в блоке PROTO www.books-shop.com Глава 6. сети в операционной системе UNIX Таблица 6.10 (продолжение) Транспортный Тип Значение примитив общения Т DISCON REQ M_PROTO Запрос на разрыв связи.

Этот примитив применим только для транспортных услуг с предварительным установлением связи. Он инициируется пользователем транспортных услуг и свидетельствует либо об отказе пользователем в установлении связи, либо о желании пользователя разорвать уже существующее соединение для дан ного потока. Сообщение состоит из одного блока за которым может следовать один или несколько блоков типа M_DATA, содержащих при кладные данные, определенные Блок M_PROTO содержит следующие поля:

PRIM_type Тип примитива — Идентификатор соединения Т DISCON IND M_PROTO Индикация разрыва связи.

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

Блок M_PROTO содержит следующие поля:

Тип примитива — T_DISCON_IND Причина разрыва связи Идентификатор соединения Т ORDREL REQ M_PROTO Запрос на "аккуратное" прекращение связи.

Этот примитив применим только для транспортных услуг с предварительным установлением связи и указывает поставщику транспортных услуг, что поль зователь завершил передачу данных. При этом со единение переходит в симплексный режим, позво ляя пользователю принимать данные от удаленного узла. Сообщение состоит из одного блока Т ORDREL IND M_PROTO Индикация "аккуратного" прекращения связи.

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

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

www.books-shop.com сети в UNIX System V Таблица 6.10 (продолжение) Транспортный Тип примитив общения Т REQ M PROTO Запрос на передачу данных.

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

Блок содержит следующие поля:

PRIM_type Тип примитива — DEST_length Размер адреса протокола Смещение адреса получателя в бло ке Размер опций ОРТ offset Смещение опций в блоке PROTO Т M PROTO Индикация получения данных.

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

Блок содержит следующие поля:

Тип примитива — Размер адреса протокола SRC_offset Смещение адреса отправителя в блоке OPT_length Размер опций ОРТ offset Смещение опций в блоке M PROTO www.books-shop.com Глава 6. сети в операционной системе UNIX Таблица 6.10 (продолжение) Транспортный Тип со Значение примитив общения Т UDERROR M PROTO Сообщение об ошибке Этот примитив применим только для транспортных услуг без предварительного установления связи и указывает пользователю, что датаграмма с указан ным адресом получателя и опциями вызвала ошиб ку. Сообщение состоит из одного блока содержащего размер адреса и сам адрес получа теля, опции, а также код ошибки, зависящий от конкретного транспортного протокола.

Блок содержит следующие поля:

Тип примитива — T_UDERROR_IND DEST_length Размер адреса протокола DEST_offset Смещение адреса отправителя в блоке Размер опций f set Смещение опций в блоке ERROR_type Код ошибки Запрос на передачу данных.

Этот примитив применим только для транспортных услуг без предварительного установления связи и информирует поставщика транспортных услуг, что сообщение содержит пакет данных интерфейса (Transport Interface Data Unit, Одно или более таких сообщений формируют пакет данных прото кола TSDU. Сообщение состоит из одного блока за которым может следовать один или несколько блоков типа содержащих при кладные данные пользователя. Блок со держит флаг lag, указывающий, является ли следующее сообщение частью того же TSDU. На основании этого флага постав щик транспортных услуг компонует транспортные пакеты TSDU. Передача данных с помощью запро сов позволяет сохранить границы записи при передаче. Заметим, что протоколом TCP данная возможность не поддерживается.

M_PROTO Индикация получения данных.

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

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

www.books-shop.com сети в UNIX System V Таблица 6.10 (продолжение) Транспортный Тип со Значение примитив общения Т EXDATA REQ M PROTO Запрос на передачу экстренных данных.

Этот примитив аналогичен но слу жит для передачи экстренных данных. Протокол TCP поддерживает передачу экстренных данных с помощью функции t_snd(3N) с аргументом flags, содержащим флаг T_EXPEDITED и, возможно, Т MORE.

Т EXDATA M PROTO Индикация получения экстренных данных.

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

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

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

Т ERROR ACK M PCPROTO Сообщение об ошибке.

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

Блок M_PCPROTO содержит следующие поля:

PRIM_type Тип примитива — Тип ошибочного примитива TLI_error Код ошибки TLI UNIX error Код системной ошибки UNIX Т INFO REQ M PCPROTO Запрос на получение параметров транспортного протокола.

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

piracy@books-shop.com 480 Глава 6. сети в операционной UNIX Таблица 6.10 (продолжение) Транспортный Тип со Значение примитив общения T_INFO_ACK M_PCPROTO Параметры транспортного протокола.

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

Блок M_PCPROTO состоит из следующих полей:

Тип примитива — T_INFO_ACK TSDU_size Определяет максимальный раз мер пакета данных протокола TSDU ETSDU_size Определяет максимальный раз мер пакета экстренных данных протокола ETSDU CDATA size Определяет максимальный обь ем данных, передаваемых при установлении связи. Соответст вует полю connect структуры функции t_open(3N) DDATA size Определяет максимальный ем данных, передаваемых при разрыве связи. Соответствует полю структуры info функции ADDR size Определяет максимальный ем транспортного протокола.

Соответствует полю addr струк туры функции OPT size Определяет размер опций для данного протокола. Соответству ет полю options структуры функции size Определяет размер пакета дан ных интерфейса TIDU SERV type Определяет тип транспортных услуг, предоставляемых постав щиком Соответствует полю servtype структуры info функции t_open(3N) CURRENT state Определяет текущее состояние поставщика транспортных услуг PROVIDER_flag Определяет дополнительные характеристики поставщика транспортных услуг www.books-shop.com в UNIX System V Таблица 6.10 (окончание) Транспортный Тип со Значение примитив общения Т REQ PROTO Управление опциями протокола.

Этот примитив позволяет пользователю получить или установить опции протокола. Сообщение со стоит из одного блока M_PROTO, включающего следующие поля:

Тип примитива — OPT_length Размер опций Смещение опций в блоке Флаги, определяющие характер запроса пользователя:

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

Т_СНЕСК — проверить, поддержи ваются ли опции, указанные поль зователем, поставщиком;

T_DAFAULT — возвратить значения опций протокола.

Т OPTMGMT АСК M PCPROTO Положительное подтверждение.

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

Взаимодействие с прикладными процессами Рассмотренный ранее программный интерфейс ТЫ полностью реализует функциональность TPI. Легко заметить соответствие между отдельными функциями ТЫ и примитивами TPI, приведенными в табл. Схема вызова функций ТЫ и обмена соответствующими примитивами TPI между клиентом и сервером для типичного TCP сеанса приведена на рис. 6.32.

Программный интерфейс потоков был рассмотрен в главе 5 при обсужде нии подсистемы STREAMS. Основными функциями, обеспечивающими передачу и получение сообщений, являются системные вызовы и getmsg(2). Таким образом, большинство функций ТЫ, составляющих про граммный интерфейс доступа прикладных процессов к транспортным про токолам, являются удобной оболочкой (реализованной в виде библиотеки, например, более фундаментальным системным вызовам и getmsg(2).

www.books-shop.com 482 Глава 6. сети в операционной UNIX Рис. 6.32. Функции TLI и примитивы TPI В качестве примера рассмотрим функцию Ее реализация может иметь следующий вид:

www.books-shop.com сети в UNIX System V int struct t_call *sndcall, struct t_call { struct struct T_conn_con struct T_ok_ack struct T_error_ack struct strbuf connect, ack, confirm, struct netbuf addr, opt, udata;

char int адреса буферов netbuf запроса sndcall*/ addr = opt = udata = поля структуры strbuf для формирования управляющей части (блок сообщения = + opt.len;

+ Т conn req) + = + buf = (char = buf;

поля заголовка блока M_PROTO сообщения в соответствии с форматом структуры connreq = (struct T_conn_req = connreq >DEST_length = connreq >DEST_offset = sizeof (struct buf += = = + buf += поля структуры strbuf для формирования блока данных (блок = = = запрос Т CONN REQ поставщику транспортных услуг по потоку &connect, к приему Выделим максимальный размер для получения негативного подтверждения, поскольку Т занимает больше = = (char является приоритетным, поэтому установим флаг RS HIPRI.

До получения подтверждения не предпринимаем никаких www.books-shop.com 484 Глава 6. сети в UNIX flags = RS_HIPRI;

(struct *)0, okack = (struct T_ok_ack получено ли положительное или негативное if == { /*Если подтверждение подготовимся к получению согласия удаленного пользователя на установление связи (примитив if (recvcall != NULL) { = opt = udata = = T_conn_con) + + = T_conn_con) + + buf = (char = buf;

= = = примитив conncon = (struct T_conn_con if == { /*Если это действительно согласие, заполним структуру rcvcall для пользователя = = offset, закончилось удачно — возвращаем } } else { /*В случае отказа мы готовы обработать примитив else www.books-shop.com сети в UNIX System V /*Если получен примитив — обработаем errack = (struct T_error_ack } } Подобным образом реализовано большинство функций ТЫ. Заметим, что в конкретном случае использования транспортного протокола TCP прием и передача данных осуществляются в виде потока, не содержащего каких либо логических записей. В этом случае не требуется формирование примитивов типа и T_DATA_IND. В то же время, для передачи и получения экстренных данных будут использованы примитивы T_EXDATA_REQ и При использовании протокола UDP все данные будут пере даваться С ПОМОЩЬЮ примитивов И Описанная реализация программного интерфейса ТЫ имеет один сущест венный недостаток — операции функций не являются атомарными. Дру гими словами, выполнение функции может быть прервано другими процессами, которые могут также связываться с удаленным узлом.

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

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

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

www.books-shop.com 486 Глава 6. сети в операционной UNIX При этом вызов ioctl(2) имеет следующий формат:

struct strioctl my strioctl;

= = = size;

= (char *)buf Интерфейс системных вызовов Рис. 6.33. Архитектура доступа к транспортным услугам При вызове ioctl(2) поле size устанавливается равным размеру соответст вующего примитива TPI, определенного полем cmd и расположенного в буфере При возврате из функции поле содержит размер прими www.books-shop.com сети в UNIX System V тива, возвращенного поставщиком транспортных услуг и расположенного в буфере Модуль служит для обработки следующих команд Значение cmd Обработка модулем Команда преобразуется в примитив T_BIND_REQ. При успеш ном завершении функции ioctl(2) в буфере buf находится при митив TI_UNBIND Команда преобразуется в примитив T_UNBIND_REQ. При ус пешном завершении функции в буфере находится примитив TI_GETINFO Команда преобразуется в примитив При успеш ном завершении функции ioctl(2) в буфере buf находится при митив Команда преобразуется в примитив При ус пешном завершении функции ioctl(2) в буфере buf находится примитив т АСК.

Интерфейс DLPI DLPI определяет интерфейс между протоколами уровня канала данных (data link layer) модели OSI, называемыми поставщиками услуг уровня ка нала данных и протоколами сетевого уровня, называемыми пользователя ми услуг уровня канала данных. В качестве примера пользователей услуг уровня канала данных можно привести такие протоколы, как IP, IPX или CLNS. С другой стороны, поставщик услуг уровня канала данных непо средственно взаимодействует с различными сетевыми устройствами, обес печивающими передачу данных по сетям различной архитектуры (например, Ethernet, FDDI или ATM) и использующими различные физи ческие среды передачи.

Для обеспечения независимости DLPI от конкретной физической сети передачи драйвер уровня канала данных состоит из двух частей: верхней аппаратно независимой и нижней аппаратно зависимой. Аппаратно неза висимая часть драйвера обеспечивает предоставление общих услуг, опре деленных интерфейсом DLPI, а также поддержку ряда потенциальных пользователей, представляющих семейства протоколов TCP/IP, NetWare и Аппаратно зависимая часть непосредственно взаимодействует с сете вым адаптером.

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

примитивы DLPI).

www.books-shop.com Глава 6. в операционной системе UNIX Во время инициализации и последующей передачи данных аппаратно не зависимая часть драйвера вызывает необходимые функции аппаратно за висимой части. Напротив, при поступлении данных из сети, аппаратно зависимая часть помещает пакеты данных, или кадры, непосредственно в очередь чтения аппаратно независимой части. Обе части совместно ис пользуют набор переменных и флагов для взаимной синхронизации и кон троля передачи.

Рис. 6.34. Структура драйвера уровня канала данных Пользователь получает доступ к услугам поставщика услуг уровня канала данных через точку доступа к услугам (Service Access Point, SAP), исполь зуя сообщения STREAMS для обмена данными. Поскольку один постав щик может иметь несколько пользователей, например IP и IPX, в его за дачу входит маршрутизация данных, полученных от физической сети, к нескольким точкам доступа. Для этого каждый пользователь идентифици рует себя с помощью адреса SAP, который сообщает поставщику, исполь зуя примитив связывания (DL_BIND_REQ) потока с точкой доступа к услу гам уровня канала данных.

Поскольку аппаратно зависимая часть драйвера может обслуживать не сколько сетевых адаптеров, каждый сетевой интерфейс идентифицируется точкой физического подключения (Physical Point of Attachment, PPA). При этом спецификация DLPI определяет два типа поставщиков услуг. По ставщик услуг первого типа (style 1) производит назначение РРА, исходя из старшего и младшего номеров используемого специального файла уст ройства (указанного в вызове Обычно каждый адаптер, обслужи ваемый драйвером, ассоциирован со старшим номером, а младший номер используется для создания клонов (см. раздел "Клоны" главы 5). Напро www.books-shop.com в UNIX System V тив, поставщик второго типа (style 2) позволяет пользователю явно указать РРА уже после открытия потока с помощью примитива присоединения Использование поставщиков второго типа является бо лее предпочтительным, например, когда одна физическая сеть поддержи вает создание независимых логических, или виртуальных каналов передачи данных (например, каналы ISDN В и D). В этом случае идентификатор РРА, передаваемый примитивом DL_ATTACH_REQ, содержит также иден тификатор логического канала. Схема описанных точек доступа приведена на рис. 6.35.

Пользователь Пользователь Пользователь услуг уровня услуг уровня услуг уровня канала данных канала данных канала данных DLPI Поставщик услуг уровня канала данных Сетевые адаптеры Рис. 6.35. Доступ к услугам поставщика услуг уровня канала данных DLPI определяет три различных режима передачи данных (или типов ус луг), позволяющих обеспечить различные требования протоколов верхнего уровня и поставщиков услуг уровня канала данных:

1. Режим с предварительным установлением связи 2. Режим без предварительного установления связи с подтверждением 3. Режим без предварительного установления связи без подтверждения В данном разделе мы остановимся только на режиме без предварительного установления связи без подтверждения. Заметим, что для традиционных технологий локальных сетей используется именно этот тип услуг уровня канала данных.

Pages:     | 1 |   ...   | 5 | 6 || 8 |



© 2011 www.dissers.ru - «Бесплатная электронная библиотека»

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