Вход/Регистрация
UNIX: разработка сетевых приложений
вернуться

Стивенс Уильям Ричард

Шрифт:

16 cmptr->cmsg_len = CMSG_LEN(sizeof(int));

17 cmptr->cmsg_level = SOL_SOCKET;

18 cmptr->cmsg_type = SCM_RIGHTS;

19 *((int*)CMSG_DATA(cmptr)) = sendfd;

20 #else

21 msg.msg_accrights = (caddr_t)&sendfd;

22 msg.msg_accrightslen = sizeof(int);

23 #endif

24 msg.msg_name = NULL;

25 msg.msg_namelen = 0;

26 iov[0].iov_base = ptr;

27 iov[0].iov_len = nbytes;

28 msg.msg_iov = iov;

29 msg.msg_iovlen = 1;

30 return (sendmsg(fd, &msg, 0));

31 }

Как и в случае функции

read_fg
, эта функция обрабатывает либо вспомогательные данные, либо права доступа, которые предшествовали вспомогательным данным в более ранних реализациях. В любом случае инициализируется структура
msghdr
и затем вызывается функция
sendmsg
.

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

read_fd
и
write_fd
, которые только что описали.

15.8. Получение информации об отправителе

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

cmsgcred
, определяемой путем включения заголовочного файла
<sys/socket.h>
. Упаковка и формат данных зависят от операционной системы. Такая возможность появилась только в BSD/OS 2.1. Мы описываем FreeBSD, а прочие варианты Unix во многом подобны ей (проблема обычно состоит в выборе структуры, которую следует использовать для передачи данных). Рассказ об этой возможности мы считаем необходимым, поскольку это важное, хотя и простое дополнение доменных протоколов Unix. Когда клиент и сервер связываются с помощью этих протоколов, серверу часто бывает необходим способ точно узнать, кто является клиентом, чтобы убедиться, что клиент имеет право запрашивать определенный сервис.

struct fcred {

uid_t fc_ruid; /* действующий идентификатор пользователя */

gid_t fc_rgid; /* действующий групповой идентификатор */

char fc_login[MAXLOGNAME]; /* имя setlogin */

uid_t fc_uid; /* идентификатор пользователя */

short fc_ngroups; /* количество групп */

gid_t fc_groups[NGROUPS]; /* дополнительные групповые идентификаторы */

};

#define fc_gid fc_groups[0] /* групповой идентификатор */

Обычно

MAXLONGNAME
и
NGROUPS
имеют значение 16. Значение
fc_ngroups
равно как минимум 1, а первым элементом массива является идентификатор группы.

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

recvmsg
с достаточно большим буфером для вспомогательных данных, чтобы туда поместились идентифицирующие данные (листинг 15.12). Однако отправитель обязан включить структуру
cmsgcred
при отправке данных посредством
sendmsg
. Хотя включение структуры осуществляется отправителем, заполняется она ядром. Благодаря этому передача идентифицирующих данных через доменный сокет Unix является надежным способом проверки клиента.

Пример

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

read_cred
, аналогичная функции
read
, но возвращающая также структуру
fcred
, содержащую идентифицирующие данные отправителя.

Листинг 15.12. Функция read_cred: чтение и возвращение идентифицирующих данных отправителя

//unixdomain/readcred.c

1 #include "unp.h"

2 #define CONTROL_LEN (sizeof(struct cmsghdr) + sizeof(struct cmsgcred))

3 ssize_t

4 read_cred(int fd, void *ptr, size_t nbytes, struct cmsgcred *cmsgcredptr)

5 {

6 struct msghdr msg;

7 struct iovec iov[1];

  • Читать дальше
  • 1
  • ...
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: