Главная страница  Взаимодействие нетривиальных процессов 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 [ 138 ] 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

на порте 111, причем как TCP, так и UDP. Соответствие номеров программ RPC их именам обычно устанавливается в файле /etc/rpc. Запустив ту же программу в BSD/OS 3.1, увидим, что в этой системе поддерживается только вторая версия программы отображения портов:

bsdi X rpdnfo -р

program vers proto port

100000 2 tcp 111 portmapper

100000 2 udp 111 portmapper

В Digital Unix 4.0B также поддерживается только вторая версия:

alpha X rpcinfo -р

program vers proto port

100000 2 tcp 111 portmapper

100000 2 udp 111 portmapper

Затем процесс сервера приостанавливает работу, ожидая поступления запросов от клиентов. Это может быть новое соединение TCP или приход дейтаграммы UDP в порт UDP. Если мы запустим rpcinfo после запуска сервера из листинга 16.3, мы увидим следующий результат:

Solaris X rpcinfo -р program vers proto port service 8243773444 1 udp 8243773444 1 tcp

где 824377344 соответствует 0x31230000 (номер программы, присвоенный ей в листинге 16.1). В том же листинге мы присвоили программе номер версии 1. Обратите внимание, что сервер готов принимать запросы от клиентов по протоколам TCP и UDP и клиент может выбирать, какой из этих протоколов он будет использовать при создании дескриптора клиента (последний аргумент с1 nt create в листинге 16.2).

3. Клиент запускается и вызывает clnt create. Аргументами (листинг 16.2) являются имя узла или IP-адрес сервера, номер программы, номер версии и строка, указывающая протокол связи. Запрос RPC направляется программе отображения портов узла сервера (для этого сообщения обычно используется протокол UDP), причем запращивается информация об указанной версии указанной программы с указанным протоколом. В случае успеха номер порта сохраняется в дескрипторе клиента для обработки всех последующих вызовов RPC через этот дескриптор.

В листинге 16.1 мы присвоили нащей программе номер 0x31230000.32-разрядные номера программ подразделяются на группы, приведенные в табл. 16.1.

Таблица 16.1. Диапазоны номеров программ для Sun RPC

Номер программы Описание

0x00000000 - Oxlfffffff

Определена Sun

0x20000000-OxSfffffff

Определена пользователем

0x40000000 - OxSfffffff

Временная (для приложений, написанных

заказчиком)

0x60000000-Oxffffffff

Зарезервированы



Программа rpci nf о выводит список программ, зарегистрированных в системе. Другим источником информации о программах RPC могут являться файлы с расширением .хв каталоге /usr/include/rpcsvc.

Inetd и серверы RPC

По умолчанию серверы, созданные с помощью rpcgen, могут вызываться сервером верхнего уровня inetd. Этот сервер описывается в разделе 12.5 [24]. Изучение содержимого заглушки сервера, создаваемой rpcgen, показывает, что при запуске функции mai п сервера она проверяет, является ли стандартный поток ввода конечной точкой XTI, и если так, то предполагается, что сервер был запущен демоном i netd.

После создания сервера RPC, который будет вызываться i netd, следует добавить информацию об этом сервере в файл /etc/i netd. conf. Туда помещаются следующие данные: имя программы RPC, поддерживаемые номера программ, протоколы и полное имя исполняемого файла сервера. В качестве примера мы приводим строку из конфигурационного файла Solaris:

rstatd/2-4 tli rpc/datagram v wait root /usr/lib/netsvc/rstat/rpc.rstatd rpc.rstatd

Первое поле содержит имя программы (которому будет сопоставлен номер с помощью файла /etc/rpc); поддерживаются версии 2, 3 и 4. Следующее поле задает конечную точку XTI (или сокет), третье поле говорит о том, что поддерживаются все протоколы видимых дейтаграмм. Если свериться с содержимым файла /etc/netconf ig, мы узнаем, что таких протоколов два: UDP и /dev/clts. Глава 29 [24] описывает этот файл и адреса XTI. Четвертое поле (wait) указывает демону i netd на необходимость ожидания завершения этого сервера перед включением режима ожидания запроса клиента для конечной точки XTI. Все серверы RPC указывают атрибут wait в конфигурационном файле /etc/i netd. conf.

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

Демон i netd создаст конечные точки XTI и зарегистрирует их в программе отображения портов для соответствующих номеров программ и версий. Мы можем убедиться в этом с помощью rpci nf о:

Solaris X rpcinfo grep statd

1000012 udp 0.0.0.0.128.11 rstatd superuser 100001 3 udp 0.0.0.0.128.11 rstatd superuser 1000014 udp 0.0.0.0.128.11 rstatd superuser

1000012 ticlts \000\000\020. rstatd superuser

1000013 ticlts \000\000\020. rstatd superuser 100001 4 ticlts \000\000\020. rstatd superuser

Четвертое поле содержит адреса XTI, причем 128 х 256 -ь И = 32 779, и данное значение является временным номером порта, присвоенным этой концевой точке и DP.

Когда дейтаграмма UDP поступает в порт 32 779, демон inetd обнаруживает готовность этой дейтаграммы к обработке и вызывает fork, а затем exec для запуска программы /usr/1 ib/netsvc/rstat/rpc. rstatd. Перед вызовами fork и exec кон-



цевая точка XTI будет скопирована в дескрипторы 0,1 и 2, а все прочие дескрипторы inetd будут закрыты (рис. 12.7 [24]). Демон inetd также прекратит слушать эту конечную точку XTI, не реагируя на запросы пользователей до тех пор, пока сервер (дочерний процесс по отношению к inetd) не завершит работу. Это поведение определяется атрибутом wait.

Предположим, что эта программа была создана с помощью rpcgen. Тогда она сможет распознать конечную точку XTI, подключенную к стандартному потоку ввода, и инициализировать ее как конечную точку сервера RPC. Это осуществляется вызовом функций RFC svc tli create и svc reg, которые в данной книге не рассматриваются. Вторая функция (вопреки названию) не регистрирует сервер в программе отображения портов - это делается лишь однажды, при запуске сервера. Функция svc run прочитает пришедшую дейтаграмму и вызовет соответствующую процедуру сервера для обработки запроса клиента.

В обычной ситуации серверы, запускаемые демоном i netd, обрабатывают один запрос клиента и завершают работу, после чего i netd переходит в режим ожидания следующего запроса. Для оптимизации работы системы серверы RPC, созданные rpcgen, ждут поступления нового запроса от клиента в течение некоторого времени (по умолчанию 2 минуты). В этом слзд1ае дейтаграмма обрабатывается уже запущенным сервером. Это исключает накладные расходы на вызов fork и exec при поступлении нескольких клиентских запросов подряд. По истечении периода ожидания сервер завершает работу, а демону i netd отсылается сигнал SIGCHLD, после чего он переходит в режим ожидания дейтаграмм по XTI.

16.4. Аутентификация

По умолчанию в запросе RPC не содержится информации о клиенте. Сервер отвечает на запрос клиента, не беспокоясь о том, что это за клиент. Это называется нулевой аутентификацией, или AUTH NONE.

Следующий уровень проверки подлинности называется аутентификацией Unix, или AUTHSYS. Клиент должен сообщить библиотеке RFC времени выполнения информацию о себе (имя узла, действующий идентификатор пользователя, действующий идентификатор группы, дополнительные идентификаторы группы) для включения в каждый запрос. Изменим программу из листинга 16.2 таким образом, чтобы она включала возможность осуществления аутентификации Unix. В листинге 16.7 приведен новый текст программы-клиента.

Листинг 16.7. Клиент, осуществляющий аутентификацию Unix

sunrpc/square4/cli ent.с

1 #include unpipc.h

2 #include square.h

3 int

4 mainCint argc. char **argv)

6 CLIENT *cl;

7 squarejn in:

8 square out out:

9 if Cargc != 3) -,

продолжение



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 [ 138 ] 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования.