Когда дейтаграмма UDP поступает в порт 32779, демон inetd обнаруживает готовность этой дейтаграммы к обработке и вызывает fork, а затем exec для запуска программы /usr/lib/netsvc/rstat/rpc.rstatd. Перед вызовами fork и exec концевая точка XTI будет скопирована в дескрипторы 0, 1 и 2, а все прочие дескрипторы inetd будут закрыты (рис. 12.7 [24]). Демон inetd также прекратит слушать эту конечную точку XTI, не реагируя на запросы пользователей до тех пор, пока сервер (дочерний процесс по отношению к inetd) не завершит работу. Это поведение определяется атрибутом wait.

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

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

<p>16.4. Аутентификация</p>

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

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

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

//sunrpc/square4/client.с

1  #include "unpipc.h"

2  #include "square.h"

3  int

4  main(int argc, char **argv)

5  {

6   CLIENT *cl;

7   square_in in;

8   square_out out;

9   if (argc != 3)

10   err_quit("usage: client hostname integer-value");

11  cl = Clnt_create(argv[1], SQUARE_PROG, SQUARE_VERS, "tcp");

12  auth_destroy(cl-cl_auth);

13  cl-cl_auth = authsys_create_default;

14  in.arg1 = atol(argv[2]);

15  if (squareproc_2(in, out, cl) != RPC_SUCCESS)

16   err_quit("%s", clnt_sperror(cl, argv[1]));

17  printf("result: %ld\n", out.resl);

18  exit(0);

19 }

12-13 Эти строки были добавлены в данной версии программы. Сначала мы вызываем auth_destroy для удаления предыдущей аутентификационной информации, связанной с данным дескриптором клиента (то есть дескриптор нулевой аутентификации, создаваемый по умолчанию). Затем вызов authsys_create_default создает соответствующую аутентификационную структуру Unix и мы сохраняем ее в поле cl_auth структуры CLIENT. Оставшаяся часть клиента не претерпела изменений по сравнению с листингом 16.5.

В листинге 16.8 приведен текст процедуры сервера, измененный по сравнению с листингом 16.6. Мы не приводим текст процедуры square_prog_2_freeresult, которая не меняется.

Листинг 16.8. Процедура сервера, запрашивающая аутентификацию Unix

//sunrpc/square4/server.c

1  #include "unpipc.h"

2  #include "square.h"

3  bool_t

4  squareproc_2_svc(square_in *inp, square_out *outp, struct svc_req *rqstp)

5  {

6   printf("thread %Id started, arg = %ld, auth = %d\n",

7   pr_thread_id(NULL), inp-arg1, rqstp-rq_cred.oa_flavor);

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже