UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
int offset = 2;
if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_CHECKSUM,
&offset, sizeof(offset)) < 0)
<i> обработка ошибки</i>
Здесь не только разрешается вычисление контрольной суммы на данном сокете, но и сообщается ядру смещение 16-разрядной контрольной суммы в байтах: в данном примере оно составляет два байта от начала данных приложения. Чтобы отключить данный параметр, ему нужно присвоить значение -1. Если он включен, ядро будет вычислять и сохранять контрольную сумму для исходящих пакетов, посланных на данном сокете, а также проверять контрольную сумму для пакетов, получаемых данным сокетом.
28.4. Ввод через символьный сокет
Первый вопрос, на который следует ответить, говоря о символьных сокетах, следующий: какие из полученных IP-дейтаграмм ядро передает символьному сокету? Применяются следующие правила:
1. Получаемые пакеты UDP и TCP никогда не передаются на символьный сокет. Если процесс хочет считать IP-дейтаграмму, содержащую пакеты UDP или TCP, пакеты должны считываться на канальном уровне, как показано в главе 29.
2. Большинство ICMP-пакетов передаются на символьный сокет, после того как ядро заканчивает обработку ICMP-сообщения. Беркли-реализации посылают все получаемые ICMP-пакеты на символьный сокет, кроме эхо-запроса, запроса отметки времени и запроса маски адреса [128, с. 302–303]. Эти три типа ICMP-сообщений полностью обрабатываются ядром.
3. Все IGMP-пакеты передаются на символьный сокет, после того как ядро заканчивает обработку IGMP-сообщения.
4. Все IP-дейтаграммы с таким значением поля протокола, которое не понимает ядро, передаются на символьный сокет. Для этих пакетов ядро выполняет только минимальную проверку некоторых полей IP-заголовка, таких как версия IP, контрольная сумма IPv4-заголовка, длина заголовка и IP-адрес получателя [128, с. 213–220].
5. Если дейтаграмма приходит фрагментами, символьному сокету ничего не передается, до тех пор, пока все фрагменты не прибудут и не будут собраны вместе.
Если у ядра есть IP-дейтаграмма для пересылки символьному сокету, в поисках подходящих сокетов проверяются все символьные сокеты всех процессов. Копия IP-дейтаграммы доставляется каждому подходящему сокету. Для каждого символьного сокета выполняются три перечисленных ниже проверки, и только в том случае, если все три проверки дают положительный результат, дейтаграмма направляется данному сокету.
1. Если при создании символьного сокета определено ненулевое значение
protocol
socket
2. Если локальный IP-адрес связан с символьным сокетом функцией
bind
3. Если для символьного сокета был определен внешний адрес с помощью функции
connect
Следует отметить, что если символьный сокет создан с нулевым значением аргумента
protocol
bind
connect
Дейтаграммы IPv4 всегда передаются через символьные сокеты целиком, вместе с заголовками. В версии IPv6 символьному сокету передается все, кроме дополнительных заголовков (см., например, рис. 28.4 и 28.6).
В заголовке IPv4, передаваемом приложению, для ip_len, ip_off и ip_id установлен порядок байтов узла, а все остальные ноля имеют порядок байтов сети. В системе Linux все поля остаются в сетевом порядке байтов.
Как уже говорилось, интерфейс символьных сокетов определяется таким образом, чтобы работа со всеми протоколами, в том числе и не обрабатываемыми ядром, осуществлялась одинаково. Поэтому содержимое полей зависит от ядра операционной системы.
В предыдущем разделе мы отметили, что все ноля символьного сокета IPv6 остаются в сетевом порядке байтов.
Фильтрация по типу сообщений ICMPv6
Символьный сокет ICMPv4 получает большинство сообщений ICMPv4, полученных ядром. Но ICMPv6 является расширением ICMPv4, включающим функциональные возможности ARP и IGMP (см. раздел 2.2). Следовательно, символьный сокет ICMPv6 потенциально может принимать гораздо больше пакетов по сравнению с символьным сокетом ICMPv4. Но большинство приложений, использующих символьные сокеты, заинтересованы только в небольшом подмножестве всех ICMP-сообщений.
Для уменьшения количества пакетов, передаваемых от ядра к приложению через символьный ICMPv6-сокет, предусмотрен фильтр, связанный с приложением. Фильтр объявляется с типом данных
struct icmp6_filter
<netinet/icmp6.h>
setsockopt
getsockopt
level
IPPROTO_ICMPV6
optname
ICMP6_FILTER
Со структурой
icmp6_filter
#include <netinet/icmp6.h>
void ICMP6_FILTER_SETPASSALL(struct icmp6_filter *<i>filt</i>);
void ICMP6_FILTER_SETBLOCKALL(struct icmp6_filter *<i>filt</i>);
void ICMP6_FILTER_SETPASS(int <i>msgtype</i>, struct icmp6_filter *<i>filt</i>);
void ICMP6_FILTER_SETBLOCK(int <i>msgtype</i>, struct icmp6_filter *<i>filt</i>);
int ICMP6_FILTER_WILLPASS(int <i>msgtype</i>, const struct icmp6_filter *<i>filt</i>);
int ICMP6_FILTER_WILLBLOCK(int <i>msgtype</i>, const struct icmp6_filter *<i>filt</i>);
<i>Все возвращают: 1, если фильтр пропускает (блокирует) сообщение данного типа, 0 в противном случае</i>
Аргумент
filt
icmp6_filter
msgtype
Макрокоманда
SETPASSALL
SETBLOCKALL