Чтение онлайн

на главную - закладки

Жанры

UNIX: разработка сетевых приложений
Шрифт:

В данном разделе предлагается решение, не требующее никаких изменений в ядре. Мы предлагаем демон ICMP-сообщений

icmpd
, который создает символьный сокет ICMPv4 и символьный сокет ICMPv6 и получает все ICMP-сообщения, направляемые к ним ядром. Он также создает потоковый сокет домена Unix, связывает его (при помощи функции
bind
) с полным именем
/tmp/icmpd
и прослушивает входящие соединения (устанавливаемые при помощи функции
connect
) клиентов с этим сокетом. Схема соединений изображена на рис. 28.7.

Рис. 28.7.

Демон icmpd: создание сокетов

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

bind
) с этим сокетом динамически назначаемый порт; для чего это делается, будет пояснено далее. Затем оно создает доменный сокет Unix и присоединяется (функция
connect
) к заранее известному полному имени файла демона. Это показано на рис. 28.8.

Рис. 28.8. Приложение создает свой сокет UDP и доменный сокет Unix

Далее приложение «передает» свой UDP-сокет демону через соединение домена Unix, используя технологию передачи дескрипторов, как показано в разделе 15.7. Такой подход позволяет демону получить копию сокета, так что он может вызвать функцию

getsockname
и получить номер порта, связанный с сокетом. На рис. 28.9 показана передача сокета.

Рис. 28.9. Пересылка сокета UDP демону через доменный сокет Unix

После того как демон получает номер порта, связанный с UDP-сокетом, он закрывает свою копию сокета, и мы возвращаемся к схеме, приведенной на рис. 28.8.

ПРИМЕЧАНИЕ

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

В таком случае в результате любой ошибки ICMP, полученной демоном в ответ на UDP-дейтаграмму, посланную с порта, который связан с UDP-сокетом приложения, демон посылает приложению сообщение (о котором мы рассказываем чуть ниже) через доменный сокет Unix. Тогда приложение должно использовать функцию

select
или
poll
, чтобы обеспечить ожидание прибытия данных либо на UDP-сокет, либо на доменный сокет Unix.

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

Листинг 28.20. Заголовочный файл unpicmpd.h

//icmpd/unpicmpd.h

1 #ifndef __unpicmp_h

2 #define __unpicmp_h

3 #include "unp.h"

4 #define ICMPD_PATH "/tmp/icmpd" /* известное имя сервера */

5 struct icmpd_err {

6 int icmpd_errno; /* EHOSTUNREACH, EMSGSIZE, ECONNREFUSED */

7 char icmpd_type; /* фактический тип ICMPv[46] */

8 char icmpd_code; /* фактический код ICMPv[46] */

9 socklen_t icmpd_len; /* длина последующей структуры sockaddr{} */

10 struct sockaddr_storage icmpd_dest; /* универсальная структура

sockaddr_storage */

11 };

12 #endif /* __unpicmp_h */

4-11
Определяются известное полное имя сервера и структура
icmpd_err
, передаваемая от сервера приложению сразу, как только получено ICMP-сообщение, которое должно быть передано данному приложению.

6-8
Проблема в том, что типы сообщений ICMPv4 отличаются численно (а иногда и концептуально) от типов сообщений ICMPv6 (см. табл. А.5 и А.6). Возвращаются реальные значения типа( type) и кода( code), но мы также отображаем соответствующие им значения
errno
(
icmpd_errno
), взятые из последнего столбца табл. А.5 и А.6. Приложение может использовать эти значения вместо зависящих от протокола значений ICMPv4 и ICMPv6. В табл. 28.1 показаны обрабатываемые сообщения ICMP и соответствующие им значения
errno
.

Таблица 28.1. Значения переменной icmpd_errno, сопоставляющей ошибки ICMPv4 и ICMPv6

icmpd_errno Ошибка ICMPv4 Ошибка ICMPv6
ECONNREFUSED Port unreachable (Порт недоступен) Port unreachable (Порт недоступен)
EMSGSIZE Fragmentation needed but DF bit set (Необходима фрагментация, но установлен бит DF) Packet too big (Слишком большой пакет)
EHOSTUNREACH Time exceeded (Превышено время передачи) Time exceeded (Превышено время передачи)
EHOSTUNREACH Source quench (Отключение отправителя)
EHOSTUNREACH Все другие сообщения о недоступности получателя (Destination unreachable) Все другие сообщения о недоступности получателя (Destination unreachable)

Демон возвращает пять типов ошибок ICMP:

1. «Port unreachable» (Порт недоступен) означает, что сокет не связан с портом получателя на IP-адресе получателя.

2. «Packet too big» (Слишком большой пакет) используется при определении транспортной MTU. В настоящее время нет определенного API, позволяющего UDP-приложениям осуществлять определение транспортной MTU. Если ядро поддерживает определение транспортной MTU для UDP, то обычно получение данной ошибки ICMP заставляет ядро записать новое значение транспортной MTU в таблицу маршрутизации ядра, но UDP-приложение, пославшее дейтаграмму, не извещается. Вместо этого приложение должно дождаться истечения тайм-аута и повторно послать дейтаграмму, и тогда ядро найдет новое (меньшее) значение MTU в своей таблице маршрутизации и фрагментирует дейтаграмму. Передача этой ошибки приложению позволяет ему ускорить повторную передачу дейтаграммы, и возможно, приложение сможет уменьшить размер посылаемой дейтаграммы.

3. Ошибка «Time exceeded» (Превышено время передачи) обычно возникает с кодом 0 и означает, что либо значение поля TTL (в случае IPv4), либо предельное количество транзитных узлов (в случае IPv6) достигло нуля. Обычно это свидетельствует о зацикливании маршрута, что, возможно, является временной ошибкой.

4. Ошибка «Source quench» (Отключение отправителя) ICMPv4 хотя и рассматривается в RFC 1812 [6] как устаревшая, может быть послана маршрутизаторами (или неправильно сконфигурированными узлами, действующими как маршрутизаторы). Такие ошибки означают, что пакет отброшен, и поэтому обрабатываются как ошибки недоступности получателя. Следует отметить, что в версии IPv6 нет ошибки отключения отправителя.

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

Сама себе хозяйка

Красовская Марианна
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Сама себе хозяйка

Сердце Дракона. Том 11

Клеванский Кирилл Сергеевич
11. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
6.50
рейтинг книги
Сердце Дракона. Том 11

Первый среди равных. Книга IV

Бор Жорж
4. Первый среди Равных
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Первый среди равных. Книга IV

Неучтенный. Дилогия

Муравьёв Константин Николаевич
Неучтенный
Фантастика:
боевая фантастика
попаданцы
7.98
рейтинг книги
Неучтенный. Дилогия

Мастер Разума IV

Кронос Александр
4. Мастер Разума
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Мастер Разума IV

Авиатор: назад в СССР

Дорин Михаил
1. Авиатор
Фантастика:
попаданцы
альтернативная история
5.25
рейтинг книги
Авиатор: назад в СССР

Кадры решают все

Злотников Роман Валерьевич
2. Элита элит
Фантастика:
боевая фантастика
попаданцы
альтернативная история
8.09
рейтинг книги
Кадры решают все

Плеяда

Суконкин Алексей
Проза:
военная проза
русская классическая проза
5.00
рейтинг книги
Плеяда

Потусторонний. Книга 2

Погуляй Юрий Александрович
2. Господин Артемьев
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Потусторонний. Книга 2

Ученик. Книга 4

Первухин Андрей Евгеньевич
4. Ученик
Фантастика:
фэнтези
5.67
рейтинг книги
Ученик. Книга 4

Законник Российской Империи. Том 3

Ткачев Андрей Юрьевич
3. Словом и делом
Фантастика:
городское фэнтези
альтернативная история
аниме
дорама
5.00
рейтинг книги
Законник Российской Империи. Том 3

Ваше Сиятельство 7

Моури Эрли
7. Ваше Сиятельство
Фантастика:
боевая фантастика
аниме
5.00
рейтинг книги
Ваше Сиятельство 7

Война

Валериев Игорь
7. Ермак
Фантастика:
боевая фантастика
альтернативная история
5.25
рейтинг книги
Война

Младший сын князя. Том 4

Ткачев Андрей Юрьевич
4. Аналитик
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Младший сын князя. Том 4