28.7. Демон сообщений ICMP

28.7. Демон сообщений ICMP

Получение асинхронных ошибок ICMP на сокет UDP всегда было и продолжает оставаться проблемой. Ядро получает сообщения об ошибках ICMP, но они редко доставляются приложениям, которым необходимо о них знать. Мы видели, что для получения этих ошибок в API сокетов требуется присоединение сокета UDP к одному IP-адресу (см. раздел 8.11). Причина такого ограничения заключается в том, что единственная ошибка, возвращаемая функцией recvfrom, является целочисленным кодом errno, а если приложение посылает дейтаграммы по нескольким адресам, а затем вызывает recvfrom, то данная функция не может сообщить приложению, какая из дейтаграмм вызвала ошибку.

В данном разделе предлагается решение, не требующее никаких изменений в ядре. Мы предлагаем демон 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. Все остальные ошибки недоступности получателя (Destination unreachble) означают, что пакет сброшен.

10 Элемент icmpd_dest является структурой адреса сокета, содержащей IP-адрес получателя и порта дейтаграммы, сгенерировавшей ICMP-ошибку. Этот элемент может быть структурой sockaddr_in для ICMPv4 либо структурой sockaddr_in6 для ICMPv6. Если приложение посылает дейтаграммы по нескольким адресам, оно, вероятно, имеет по одной структуре адреса сокета на каждый адрес. Возвращая эту информацию в структуре адреса сокета, приложение может сравнить ее со своими собственными структурами для поиска той, которая вызвала ошибку. Тип sockaddr_storage используется для того, чтобы в структуре можно было хранить адреса любого типа, поддерживаемого системой.

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

Получение и пересылка сообщений. Создание ответных сообщений

Из книги Office 2007. Мультимедийный курс автора Мединов Олег

Получение и пересылка сообщений. Создание ответных сообщений Чтобы получить новую почту, выполните команду главного меню Сервис ? Отправить/Получить ? Доставить почту либо нажмите клавишу F9. Все полученные почтовые сообщения будут помещены в папку Входящие и помечены


5.8.1. Демон Syslogd

Из книги Linux-сервер своими руками автора Колисниченко Денис Николаевич


5.8.5. Демон klogd

Из книги Искусство программирования для Unix автора Реймонд Эрик Стивен

5.8.5. Демон klogd Демон klogd предназначен для перехвата и протоколирования сообщений ядра Linux (klogd расшифровывается как kernel-logging daemon). В своей работе вы можете использовать параметры демона, указанные в табл. 5.9.Параметры демона klogd Таблица 5.9 Параметр Описание -c n


11.6.8.2. Пара спулер/демон

Из книги Искусство программирования для Unix автора Реймонд Эрик Стивен

11.6.8.2. Пара спулер/демон Облегченный вариант пары конфигуратор/актор может оказаться полезным в ситуациях, когда требуется сериализованный доступ к общему ресурсу в пакетном режиме, т.е. когда четко определенный поток заданий или последовательность запросов требует


11.6.8.2. Пара спулер/демон

Из книги Linux: Полное руководство автора Колисниченко Денис Николаевич

11.6.8.2. Пара спулер/демон Облегченный вариант пары конфигуратор/актор может оказаться полезным в ситуациях, когда требуется сериализованный доступ к общему ресурсу в пакетном режиме, т.е. когда четко определенный поток заданий или последовательность запросов требует


19.2.1. Демон routed

Из книги Linux глазами хакера автора Флёнов Михаил Евгеньевич

19.2.1. Демон routed Стандартной программой маршрутизации в Linux является демон routed. Этот демон, как правило, настраивается сам (динамически) и не требует конфигурирования. Обнаруженные маршруты он заносит в маршрутную таблицу ядра.В своей работе демон routed использует протокол


27.2 Протокол ICMP

Из книги Операционная система UNIX автора Робачевский Андрей М.

27.2 Протокол ICMP 27.2.1. Для чего используется протокол ICMP Протокол межсетевых управляющих сообщений используется для диагностических целей. Например, система А передала системе Б неверный пакет. Система Б с помощью протокола ICMP может «сказать» системе А, что посланный ею


5.4. Демон inetd/xinetd

Из книги UNIX: разработка сетевых приложений автора Стивенс Уильям Ричард

5.4. Демон inetd/xinetd Для того чтобы сервер смог обрабатывать запросы клиентов, программа должна быть постоянно загружена и связана с определенным портом. В этом нет ничего сложного, но зачем постоянно держать программу в памяти, особенно если она слишком большая, а работает


Демон

Из книги Разработка ядра Linux автора Лав Роберт

Демон Демоны играют важную роль в работе операционной системы. Достаточно будет сказать, что возможность терминального входа пользователей в систему, доступ по сети, использование системы печати и электронной почты, — все это обеспечивается соответствующими демонами


13.2. Демон syslogd

Из книги The Intel [Как Роберт Нойс, Гордон Мур и Энди Гроув создали самую влиятельную компанию в мире] автора Мэлоун Майкл

13.2. Демон syslogd Системы Unix обычно запускают демон syslogd в одном из сценариев инициализации системы, и он функционирует, пока система работает. Реализации syslogd, происходящие от Беркли, выполняют при запуске следующие действия:1. Считывается файл конфигурации, обычно /etc/syslog.conf,


13.5. Демон inetd

Из книги Linux и все, все, все... Статьи и колонки в LinuxFormat, 2006-2013 автора Федорчук Алексей Викторович

13.5. Демон inetd В типичной системе Unix может существовать много серверов, ожидающих запроса клиента. Примерами являются FTP, Telnet, Rlogin, TFTP и т.д. В системах, предшествующих 4.3BSD, каждая из этих служб имела связанный с ней процесс. Этот процесс запускался во время загрузки из файла


Демон icmpd

Из книги автора

Демон icmpd Начинаем описание нашего демона icmpd с заголовочного файла icmpd.h, приведенного в листинге 28.23.Листинг 28.23. Заголовочный файл icmpd.h для демона icmpd//icmpd/icmpd.h 1 #include "unpicmpd.h" 2 struct client { 3  int connfd; /* потоковый доменный сокет Unix к клиенту */ 4  int family; /* AF_INET или AF_INET6 */ 5  int lport;  /*


Демон ksoftirqd

Из книги автора

Демон ksoftirqd Обработка отложенных прерываний (softirq) и, соответственно, тасклетов может осуществляться с помощью набора потоков пространства ядра (по одному потоку на каждый процессор). Потоки пространства ядра помогают обрабатывать отложенные прерывания, когда система


Демон pdflush

Из книги автора

Демон pdflush Измененные (dirty, "грязные") страницы памяти когда-нибудь должны быть записаны на диск. Обратная запись страниц памяти выполняется в следующих двух случаях.• Когда объем свободной памяти становится меньше определенного порога, ядро должно записать измененные


Пердем – персональный демон

Из книги автора

Пердем – персональный демон LinuxFormat #112 (декабрь 2008)Все знают, что пермаш – это персональная машина, пердач – персональная дача, перпен – это... нет, не то, что вы подумали, а персональная пенсия, и так далее. А вот что такое пердем? Это – персональный демон, система PC-BSD,