Уильям Стивенс - UNIX: разработка сетевых приложений
- Название:UNIX: разработка сетевых приложений
- Автор:
- Жанр:
- Издательство:Питер
- Год:2007
- Город:Санкт-Петербург
- ISBN:5-94723-991-4
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Уильям Стивенс - UNIX: разработка сетевых приложений краткое содержание
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
UNIX: разработка сетевых приложений - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
4. Если ваша система поддерживает вызов SIOCGIGNUM
функции ioctl
, измените листинг 17.4 так, чтобы запустить этот вызов, и используйте возвращаемое значение как начальный размер буфера.
Глава 18
Маршрутизирующие сокеты
18.1. Введение
Традиционно доступ к таблице маршрутизации Unix внутри ядра осуществлялся с помощью команд функции ioctl
. В разделе 17.9 мы описали две операции: SIOCADDRT
и SIOCDELRT
, предназначенные для добавления и удаления маршрута. Мы также отметили, что не существует операции чтения всей таблицы маршрутизации — вместо этого программы, такие как netstat
, считывают память ядра, для того чтобы получить содержимое таблицы маршрутизации. И еще одно добавление. Демонам маршрутизации, таким как gated
, необходимо отслеживать сообщения ICMP (Internet Control Message Protocol — протокол управляющих сообщений Интернета) об изменении маршрутов, получаемых ядром, и для этого они часто создают символьный (неструктурированный) сокет ICMP (см. главу 28), а затем прослушивают на этом сокете все получаемые сообщения ICMP.
В 4.3BSD Reno интерфейс подсистемы маршрутизации ядра был упрощен за счет создания семейства адресов (домена) AF_ROUTE
. Единственный тип сокетов, поддерживаемый для этого семейства, — это символьный сокет (raw socket). Маршрутизирующие сокеты поддерживают три типа операций.
1. Процесс может отправить ядру сообщение, записав его в маршрутизирующий сокет. Таким образом добавляются и удаляются маршруты.
2. Процесс может прочитать сообщение от ядра через маршрутизирующий сокет. Так ядро уведомляет процесс о том, что сообщение ICMP об изменении маршрутизации было получено и обработано.
Некоторые операции включают оба шага: например, процесс отправляет ядру сообщение через маршрутизирующий сокет, запрашивая всю информацию по данному маршруту, после чего через маршрутизирующий сокет считывает ответ ядра.
3. Процесс может использовать функцию sysctl
(см. раздел 18.4) либо для просмотра таблицы маршрутизации, либо для перечисления всех сконфигурированных интерфейсов.
Первые две операции требуют прав привилегированного пользователя, а третью операцию может выполнить любой процесс.
Некоторые версии Unix из более новых ослабили требование к правам пользователя для операции открытия маршрутизирующего сокета и ограничивают только передачу сообщений, изменяющих таблицу маршрутизации ядра. Это позволяет любому процессу узнать маршрут при помощи команды RTM_GET, не являясь суперпользователем.
Технически третья операция выполняется при помощи общей функции sysctl, а не маршрутизирующего сокета. Но мы увидим, что среди ее входных параметров есть семейство адресов (для описываемых в этой главе операций используется семейство AF_ROUTE), а результат она возвращает в том же формате, который используется ядром для маршрутизирующего сокета. Действительно, в ядре 4.4BSD обработка функции sysctl для семейства AF_ROUTE является частью кода маршрутизирующего сокета [128, с. 632–643].
Функция sysctl появилась в 4.4BSD. К сожалению, не все реализации, поддерживающие маршрутизирующие сокеты, предоставляют ее. Например, AIX 4.2, Digital Unix 4.0 и Solaris 2.6 поддерживают маршрутизирующие сокеты, но ни одна из этих систем не поддерживает утилиту sysctl.
18.2. Структура адреса сокета канального уровня
Структуры адреса сокета канального уровня будут встречаться нам как значения, содержащиеся в некоторых сообщениях, возвращаемых на маршрутизирующем сокете. В листинге 18.1 [1] Все исходные коды программ, опубликованные в этой книге, вы можете найти по адресу http://www.piter.com.
показано определение структуры, задаваемой в заголовочном файле .
Листинг 18.1. Структура адреса сокета канального уровня
struct sockaddr_dl {
uint8_t sdl_len;
sa_family_t sdl_family; /* AF_LINK */
uint16_t sdl_index; /* индекс интерфейса, присвоенный системой,
если > 0 */
uint8_t sdl_type; /* тип интерфейса из .
IFT_ETHER и т.д. */
uint8_t sdl_nlen; /* длина имени, начинается с sdl_data[0] */
uint8_t sdl_alen; /* длина адреса канального уровня */
uint8_t sdl_slen; /* адрес селектора канального уровня */
char sdl_data[12]; /* минимальная рабочая область.
может быть больше; содержит имя
интерфейса и адрес канального уровня */
};
У каждого интерфейса имеется уникальный положительный индекс. Далее в этой главе мы увидим, каким образом он возвращается функциями if_nametoindex
и if_nameindex
. В главе 21 при обсуждении параметров многоадресных сокетов IPv6 и в главе 27 при обсуждении дополнительных параметров сокетов IPv6 и IPv4 мы вновь вернемся к этим функциям.
Элемент sdl_data
содержит и имя, и адрес канального уровня (например, 48-разрядный MAC-адрес интерфейса Ethernet). Имя начинается с sdl_data[0]
и не заканчивается нулем. Начало адреса канального уровня смещено на sdl_nlen
байтов относительно начала имени. В этом заголовочном файле для возвращения указателя на адрес канального уровня задается следующий макрос:
#define LLADDR(s) ((caddr_t)((s)->sdl_data + (s)->sdl_nlen))
Эти структуры адреса сокета имеют переменную длину [128, с. 89]. Если адрес канального уровня и имя превышают 12 байт, размер структуры будет больше 20 байт. В 32-разрядных системах размер обычно округляется в большую сторону, до следующего числа, кратного 4 байтам. Мы также увидим на рис. 22.1, что когда одна из этих структур возвращается параметром сокета IP_RECVIF
, все три длины становятся нулевыми, а элемента sdl_data
не существует.
18.3. Чтение и запись
Создав маршрутизирующий сокет, процесс может отправлять ядру команды путем записи в этот сокет и считывать из него информацию от ядра. Существует 12 различных команд маршрутизации, 5 из которых могут быть запущены процессом. Они определяются в заголовочном файле и показаны в табл. 18.1.
Таблица 18.1. Типы сообщений, проходящих по маршрутизирующему сокету
Тип сообщения | К ядру? | От ядра? | Описание | Тип структуры |
---|---|---|---|---|
RTM_ADD | • | • | Добавить маршрут | rt_msghdr |
RTM_CHANGE | • | • | Поменять шлюз, метрику или флаги | rt_msghdr |
RTM_DELADDR | • | Адрес был удален из интерфейса | ifa_msghdr | |
RTM_DELETE | • | • | Удалить маршрут | rt_msghdr |
RTM_GET | • | • | Сообщить о метрике и других характеристиках маршрута | rt_msghdr |
RTM_IFINFO | • | Находится ли интерфейс в активном состоянии | if_msghdr | |
RTM_LOCK | • | • | Блокировка указанной метрики | rt_msghdr |
RTM_LOSING | • | Возможно, неправильный маршрут | rt_msghdr | |
RTM_MISS | • | Поиск этого адреса завершился неудачно | rt_msghdr | |
RTM_NEWSDDR | • | Адрес добавлен к интерфейсу | ifa_msghdr | |
RTM_NEWMDDR | • | Групповой адрес добавлен к интерфейсу | ifma_msghdr | |
RTM_REDIRECT | • | Ядро получило указание использовать другой маршрут | rt_msghdr | |
RTM_RESOLVE | • | Запрос на определение адреса канального уровня по адресу получателя | rt_msghdr |
На маршрутизирующем сокете происходит обмен пятью различными структурами, как показано в последнем столбце таблицы: rt_msghdr
, if_msghdr
, if_announcemsghdr
, ifma_msghdr
и ifa_msghdr
. Эти структуры представлены в листинге 18.2.
Интервал:
Закладка: