Уильям Стивенс - UNIX: разработка сетевых приложений
- Название:UNIX: разработка сетевых приложений
- Автор:
- Жанр:
- Издательство:Питер
- Год:2007
- Город:Санкт-Петербург
- ISBN:5-94723-991-4
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Уильям Стивенс - UNIX: разработка сетевых приложений краткое содержание
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
UNIX: разработка сетевых приложений - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
78 addrext->sadb_address_len = (sizeof(*addrext) + salen(dst) + 7) / 8;
79 addrext->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
80 addrext->sadb_address_proto = 0; /* any protocol */
81 addrext->sadb_address_prefixlen = prefix_all(dst);
82 addrext->sadb_address_reserved = 0;
83 memcpy(addrext + 1, dst, salen(dst));
84 len += addrext->sadb_address_len * 8;
85 p += addrext->sadb_address_len * 8;
86 keyext = (struct sadb_key*)p;
87 /* обеспечивает выравнивание */
88 keyext->sadb_key_len = (sizeof(*keyext) + (keybits / 8) + 7) / 8;
89 keyext->sadb_key_exttype = SADB_EXT_KEY_AUTH;
90 keyext->sadb_key_bits = keybits;
91 keyext->sadb_key_reserved = 0;
92 memcpy(keyext + 1, keydata, keybits / 8);
93 len += keyext->sadb_key_len * 8;
94 p += keyext->sadb_key_len * 8;
95 msg->sadb_msg_len = len / 8;
96 printf("Sending add message:\n");
97 print_sadb_msg(buf, len);
98 Write(s, buf, len);
99 printf("\nReply returned:\n");
100 /* считывание и вывод ответа SADB_ADD, игнорируя любые другие */
101 for (;;) {
102 int msglen;
103 struct sadb_msg *msgp;
104 msglen = Read(s, &buf, sizeof(buf));
105 msgp = (struct sadb_msg*)&buf;
106 if (msgp->sadb_msg_pid == mypid &&
107 msgp->sadb_msg_type == SADB_ADD) {
108 print_sadb_msg(msgp, msglen);
109 break;
110 }
111 }
112 close(s);
113 }
55-56
Как и в предыдущей программе, мы открываем сокет PF_KEY и сохраняем идентификатор нашего процесса для последующего его использования.
47-56
Мы формируем заголовок сообщения SADB_ADD
. Поле sadb_msg_len
устанавливается непосредственно перед отправкой сообщения, поскольку оно должно соответствовать истинной его длине. В переменной len
хранится текущая длина сообщения, а указатель р всегда указывает на первый неиспользуемый байт буфера.
57-67
Мы добавляем обязательное расширение SA
(см. листинг 19.3). Поле sadb_sa_spi
должно иметь сетевой порядок байтов, поэтому нам приходится применять функцию htonl
к значению в порядке байтов узла. Мы отключаем защиту от повторов и устанавливаем состояние SA
равным SADB_SASTATE_MATURE
(см. табл. 19.4). Алгоритм аутентификации выбирается в соответствии с аргументом командной строки, а шифрование отключается при помощи константы SADB_EALG_NONE
.
68-76
К сообщению добавляется расширение SADB_EXT_ADDRESS_SRC
, содержащее адрес отправителя для соглашения о безопасности.
Значение протокола устанавливается равным нулю, что подразумевает действительность соглашения для всех протоколов. Длина префикса устанавливается равной соответствующей длине версии IP (то есть 32 разряда для IPv4 и 128 разрядов для IPv6). При расчете значения поля длины мы добавляем к реальному значению число 7 перед делением на 8, что гарантирует выравнивание по 64-разрядной границе, обязательное для всех расширений, передаваемых через сокеты PF_KEY. Структура sockaddr
копируется в буфер после заголовка расширения.
77-85
Адрес получателя добавляется в сообщение SADB_EXT_ADDRESS_DST
. Процедура в точности совпадает с описанной выше.
86-94
К сообщению добавляется расширение SADB_EXT_KEY_AUTH
, содержащее ключ авторизации. Расчет поля длины производится точно так же, как и для обоих адресов. Ключ переменной длины требует соответствующего количества дополняющих нулей. Мы устанавливаем значение количества битов и копируем ключ вслед за заголовком расширения.
95-98
Мы выводим сообщение на экран вызовом функции print_sadb_msg
, после чего записываем его в сокет.
99-111
Мы считываем все сообщения из сокета до тех пор, пока не будет получено сообщение, адресованное нашему процессу (проверяется по PID) и имеющее тип SADB_ADD
. Это сообщение выводится на экран функций print_sadb_msg
, после чего программа завершает работу.
Пример
Мы запускаем программу, требуя от нее установки соглашения о безопасности, касающегося трафика между узлами 127.0.0.1 и 127.0.0.1 (то есть локального трафика):
macosx % add 127.0.0.1 127.0.0.1 HMAC-SHA-1-96 160 \
0123456789abcdef0123456789abcdef01234567
Sending add message:
SADB Message Add, errno 0, satype IPsec AH, seq 0, pid 6246
SA: SPI=39030 Replay Window=0 State=Mature
Authentication Algorithm: HMAC-SHA-1
Encryption Algorithm: None
Source address: 127.0.0.1/32
Dest address: 127.0.0.1/32
Authentication key. 160 bits: 0x0123456789abcdef0123456789abcdef01234567
Reply returned:
SADB Message Add, errno 0, satype IPsec AH, seq 0, pid 6246
SA: SPI=39030 Replay Window=0 State=Mature
Authentication Algorithm: HMAC-SHA-1
Encryption Algorithm: None
Source address: 127.0.0.1/32
Dest address: 127.0.0.1/32
Обратите внимание, что в ответе системы отсутствует ключ. Дело в том; что ответ направляется на все сокеты PF_KEY, которые, однако, могут принадлежать к разным доменам, а данные о ключах не должны передаваться между доменами. После добавления записи в базу данных мы даем команду ping 127.0.0.1
, чтобы проверить, задействуется ли соглашение о безопасности, после чего запрашиваем дамп базы данных и смотрим, что в ней изменилось.
macosx % dump
Sending dump message:
SADB Message Dump, errno 0, satype Unspecified, seq 0, pid 6283
Messages returned:
SADB Message Dump, errno 0, satype IPsec AH, seq 0, pid 6283
SA: SPI=39030 Replay Window=0 State=Mature
Authentication Algorithm: HMAC-SHA-1
Encryption Algorithm: None
[unknown extension 19]
Current lifetime:
36 allocations. 0 bytes
added at Thu Jun 5 21:01:31 2003, first used at Thu Jun 5 21:15:07 2003
Source address: 127.0.0.1/128 (IP proto 255)
Dest address: 127.0.0.1/128 (IP proto 255)
Authentication key. 160 bits: 0x0123456789abcdef0123456789abcdef01234567
Из этого дампа видно, что ядро изменило значение протокола с 0 на 255. Это артефакт реализации, а не общее свойство сокетов PF_KEY. Кроме того, ядро изменило длину префикса с 32 на 128. Это какая-то проблема, связанная с протоколами IPv4 и IPv6. Ядро возвращает расширение (с номером 19), которое не обрабатывается нашей программой выведения дампа. Неизвестные расширения пропускаются (их длина имеется в соответствующем поле). Наконец, возвращается расширение времени жизни (листинг 19.7), содержащее информацию о текущем времени жизни соглашения о безопасности.
Листинг 19.7. Структура расширения времени жизни
struct sadb_lifetime {
u_int16_t sadb_lifetime_len; /* длина расширения / 8 */
u_int16_t sadb_lifetime_exttype; /* SADB_EXT_LIFETIME_{SOFT,HARD,CURRENT} */
u_int32_t sadb_lifetime_allocations; /* количество соединений, конечных
точек или потоков */
u_int64_t sadb_lifetime_bytes; /* количество байтов */
u_int64_t sadb_lifetime_addtime; /* время создания либо время от создания
до устаревания */
u_int64_t sadb_lifetime_usetime; /* время первого использования или время от
Интервал:
Закладка: