Литмир - Электронная Библиотека
Содержание  
A
A

Исходящий и входящий интерфейсы

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

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

Адрес отправителя и адрес получателя IPv6

IPv6-адрес отправителя обычно определяется при помощи функции

bind
. Но если адрес отправителя поставляется вместе с данными, это может снизить непроизводительные затраты. Этот параметр также позволяет серверу гарантировать, что адрес отправителя ответа совпадает с адресом получателя клиентского запроса — некоторым клиентам требуется такое условие, которое сложно выполнить в случае IPv4 (см. упражнение 22.4).

Когда IPv6-адрес отправителя задан в качестве вспомогательных данных и элемент

ipi6_addr
структуры
in6_pktinfo
имеет значение
IN6ADDR_ANY_INIT
, возможны следующие сценарии: если адрес в настоящий момент связан с сокетом, он используется в качестве адреса отправителя; если в настоящий момент никакой адрес не связан с сокетом, ядро выбирает адрес отправителя. Если же элемент
ipi6_addr
не является неопределенным адресом, но сокет уже связался с адресом отправителя, то значением элемента
ipi6_addr
перекрывается уже связанный адрес, но только для данной операции вывода. Затем ядро проверяет, действительно ли запрашиваемый адрес отправителя является адресом направленной передачи, присвоенным узлу.

Когда структура in6_

pktinfo
возвращается в качестве вспомогательных данных функцией
recvmsg
, элемент
ipi6_addr
содержит IPv6-адрес получателя из полученного пакета. По сути, это аналог параметра сокета
IP_RECVDSTADDR
для IPv4.

Задание и получение предельного количества транзитных узлов

Предельное количество транзитных узлов обычно задается параметром сокета

IPV6_UNICAST_HOPS
для дейтаграмм направленной передачи (см. раздел 7.8) или параметром сокета
IPV6_MULTICAST_HOPS
для дейтаграмм многоадресной передачи (см. раздел 21.6). Задавая предельное количество транзитных узлов в составе вспомогательных данных, мы можем заменить как значение этого предела, задаваемое ядром по умолчанию, так и ранее заданное значение — и для направленной, и для многоадресной передачи, но только для одной операции вывода. Предел количества транзитных узлов полученного пакета используется в таких программах, как
traceroute
, и в некоторых приложениях IPv6, которым нужно проверять, что полученное значение равно 255 (то есть что пакет не пересылался маршрутизаторами).

Полученное предельное количество транзитных узлов возвращается в виде вспомогательных данных функцией

recvmsg
, только если приложение включает параметр сокета
IPV6_RECVHOPLIMIT
. В структуре
cmsghdr
, содержащей эти вспомогательные данные, элемент
cmsg_level
будет иметь значение
IPPROTO_IPV6
, элемент
cmsg_type
 — значение
IPV6_HOPLIMIT
, а первый байт данных будет первым байтом целочисленного предела повторных передач. Мы показали это на рис. 22.5. Нужно понимать, что значение, возвращаемое в качестве вспомогательных данных, — это действительное значение из полученной дейтаграммы, в то время как значение, возвращаемое функцией
getsockopt
с параметром
IPV6_UNICAST_HOPS
, является значением по умолчанию, которое ядро будет использовать для исходящих дейтаграмм на сокете.

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

sendmsg
. Обычные значения для предельного количества транзитных узлов лежат в диапазоне от 0 до 255 включительно, но если целочисленное значение равно -1, это указывает ядру, что следует использовать значение по умолчанию.

ПРИМЕЧАНИЕ

Предельное количество транзитных узлов не содержится в структуре in6_pktinfo — некоторые серверы UDP хотят отвечать на запросы клиентов, посылая ответы на том же интерфейсе, на котором был получен запрос, с совпадением IPv6-адреса отправителя ответа и IPv6-адреса получателя запроса. Для этого приложение может включить параметр сокета IPV6_RECVPKTINFO, а затем использовать полученную управляющую информацию из функции recvmsg в качестве управляющей информации для функции sendmsg при отправке ответа. Приложению вообще никак не нужно проверять или изменять структуру in6_pktinfo. Но если в этой структуре содержался бы предел количества транзитных узлов, приложение должно было бы проанализировать полученную управляющую информацию и изменить значение этого предела, поскольку полученный предел не является желательным значением для исходящего пакета.

Задание адреса следующего транзитного узла

Объект вспомогательных данных

IPV6_NEXTHOP
задает адрес следующего транзитного узла дейтаграммы в виде структуры адреса сокета. В структуре
cmsghdr
, содержащей эти вспомогательные данные, элемент
cmsg_level
будет иметь значение
IPPROTO_IPV6
, элемент
cmsg_type
— значение
IPV6_NEXTHOP
, а первый байт данных будет первым байтом структуры адреса сокета.

На рис. 22.5 мы показали пример такого объекта вспомогательных данных, считая, что структура адреса сокета — это 24-байтовая структура

sockaddr_in6
. В этом случае узел, идентифицируемый данным адресом, должен быть соседним для отправляющего узла. Если этот адрес совпадает с адресом получателя IPv6-дейтаграммы, мы получаем эквивалент параметра сокета
SO_DONTROUTE
. Установка этого параметра требует прав привилегированного пользователя. Адрес следующего транзитного узла можно устанавливать для всех пакетов на сокете, если включить параметр сокета
IPV6_NEXTHOP
со значением
sockaddr_in6
(раздел 27.7). Для этого необходимо обладать правами привилегированного пользователя.

Задание и получение класса трафика

Объект вспомогательных данных

IPV6_TCLASS
задает класс трафика для дейтаграммы. Элемент
cmsg_level
структуры
cmsghdr
, содержащей эти данные, будет равен
IPPROTO_IPV6
, элемент
cmsg_type
будет равен
IPV6_TCLASS
, а первый байт данных будет первым байтом целочисленного (4-байтового) значения класса трафика (см. рис. 22.5). Согласно разделу А.3, класс трафика состоит из полей
DSCP
и
ECN
. Эти поля должны устанавливаться одновременно. Ядро может маскировать или игнорировать указанное пользователем значение, если ему это нужно (например, если ядро реализует
ECN
, оно может установить биты
ECN
равными какому-либо значению, игнорируя два бита, указанных с параметром
IPV6_TCLASS
). Класс трафика обычно лежит в диапазоне 0–255. Значение -1 говорит ядру о необходимости использовать значение по умолчанию.

256
{"b":"225366","o":1}