■ IP_ADD_MEMBERSHIP
, IPV6_JOIN_GROUP
, MCAST_JOIN_GROUP
. Назначение этих параметров — присоединение к группе на заданном локальном интерфейсе. Мы задаем локальный интерфейс одним из его направленных адресов для IPv4 или индексом интерфейса для IPv6. Следующие три структуры используются при присоединении к группе или при отсоединении от нее:
struct ip_mreq {
struct in_addr imr_multiaddr; /* IPv4-адрес многоадресной
передачи класса D */
struct in_addr imr_interface; /* IPv4-адрес локального
интерфейса */
};
struct ipv6_mreq {
struct in6_addr ipv6mr_multiaddr; /* IPv6-адрес многоадресной
передачи */
unsigned int ipv6mr_interface; /* индекс интерфейса или 0 */
};
struct group_req {
unsigned int gr_interface; /* индекс интерфейса или 0 */
struct sockaddr_storage gr_group; /* адрес многоадресной передачи
IPv4 или IPv6 */
};
Если локальный интерфейс задается как универсальный адрес (INADDR_ANY
для IPv4) или как нулевой индекс IPv6, то конкретный локальный интерфейс выбирается ядром.
Мы говорим, что узел принадлежит к данной группе на данном интерфейсе, если один или более процессов в настоящий момент принадлежат к этой группе на этом интерфейсе.
Сокет может быть присоединен к нескольким группам, но к каждой группе должен быть присоединен уникальный адрес или уникальный интерфейс. Это свойство можно использовать на узле с несколькими сетевыми интерфейсами: создается один сокет, которому присваивается один адрес многоадресной передачи, но благодаря наличию разных интерфейсов этот сокет может быть присоединен к разным группам.
Вспомните из табл. 21.1, что частью адреса многоадресной передачи IPv6 является поле области действия. Как мы отмечали, адреса многоадресной передачи IPv6, отличающиеся только областью действия, являются различными. Следовательно, если реализация протокола синхронизации времени (network time protocol, NTP) хочет получать все пакеты NTP независимо от их области действия, она должна будет присоединиться к адресу ff01:101
(локальный в пределах узла), ff02:101
(локальный в пределах физической сети), ff05:101
(локальный в пределах сайта), ff08:101
(локальный в пределах организации) и ff0e:101
(глобальный). Все присоединения могут выполняться на одном сокете. Можно установить параметр сокета IPV6_PKTINFO
(см. раздел 22.8), чтобы функция recvmsg возвращала адрес получателя каждой дейтаграммы.
Независимый от версии IP параметр сокета (MCAST_JOIN_GROUP
) аналогичен соответствующему параметру IPv6 за тем исключением, что он использует структуру sockaddr_storage
вместо in6_addr
для передачи адреса ядру. Структура sockaddr_storage
(см. листинг 3.4) достаточно велика для хранения адреса любой версии, поддерживаемой системой.