Вместо того чтобы отсылать эти параметры при каждом вызове функции
sendmsg
, мы можем установить соответствующие параметры сокета. Параметры сокета используют те же константы, что и вспомогательные данные, то есть уровень параметра всегда должен иметь значение
IPPROTO_IPV6
, а название параметра может быть
IPV6_DSTOPTS
,
IPV6_HOPLIMIT
,
IPV6_HOPOPTS
,
IPV6_NEXTHOP
,
IPV6_PKTINFO
,
IPV6_RTHDR
или
IPV6_TCLASS
. Закрепленные параметры могут быть заменены для конкретного пакета в случае сокета UDP или символьного сокета IPv6, если при вызове функции
sendmsg
задать какие-либо другие параметры в качестве объектов вспомогательных данных. Если при вызове функции
sendmsg
указаны какие-либо вспомогательные данные, ни один из закрепленных параметров не будет послан с этим пакетом.
Концепция закрепленных параметров также может быть использована и в случае TCP, поскольку вспомогательные данные никогда не отсылаются и не принимаются с помощью функций
sendmsg
или
recvmsg
на сокете TCP. Вместо этого приложение TCP может установить соответствующий параметр сокета и указать любой из упомянутых в начале этого раздела семи объектов вспомогательных данных. Тогда эти параметры будут относиться ко всем пакетам, отсылаемым с данного сокета. Поведение при повторной передаче пакетов, первоначально переданных до изменения закрепленных параметров, не определено: могут использоваться как старые, так и новые значения параметров.
Не существует способа получить параметры, принятые в IP-пакете по TCP, потому что в этом протоколе отсутствует соответствие между пакетами и операциями чтения из сокета, выполняемыми пользователем.
27.8. История развития интерфейса IPv6
Документ RFC 2292 [113] определял более раннюю версию описываемого интерфейса, которая была реализована в некоторых системах. В этой версии для работы с параметрами получателя и транзитных узлов использовались функции
inet6_option_space
,
inet6_option_init
,
inet6_option_append
,
inet6_option_alloc
,
inet6_option_next
и
inet6_option_find
. Эти функции работали непосредственно с объектами типа
struct cmsghdr
, предполагая, что все параметры содержатся во вспомогательных данных. Для работы с заголовками маршрутизации были предназначены функции
inet6_rthdr_space
,
inet6_rthdr_init
,
inet6_rthdr_add
,
inet6_rthdr_lasthop
,
inet6_rthdr_reverse
,
inet6_rthdr_segments
,
inet6_rthdr_getaddr
и
inet6_rthdr_getflags
. Эти функции также работали непосредственно со вспомогательными данными.
В этом API закрепленные параметры устанавливались при помощи параметра сокета
IPV6_PKTOPTIONS
. Объекты вспомогательных данных при этом передавались в качестве данных параметра
IPV6_PKTOPTIONS
. Нынешние параметры сокета
IPV6_DSTOPTS
,
IPV6_HOPOPTS
и
IPV6_RTHDR
были флагами, позволявшими получать соответствующие заголовки во вспомогательных данных.
Подробнее обо всем этом вы можете прочесть в разделах 4–8 документа RFC 2292 [113].
27.9. Резюме
Из десяти определенных в IPv4 параметров наиболее часто используются параметры маршрутизации от отправителя, но в настоящее время их популярность падает из-за проблем, связанных с безопасностью. Доступ к параметрам заголовков IPv4 осуществляется с помощью параметра сокета
IP_OPTIONS
.
В IPv6 определены шесть заголовков расширения. Доступ к заголовкам расширения IPv6 осуществляется с помощью функционального интерфейса, что освобождает нас от необходимости углубляться в детали фактического формата пакета. Эти заголовки расширения записываются как вспомогательные данные функцией
sendmsg
и возвращаются функцией
recvmsg
также в виде вспомогательных данных.
Упражнения
1. Что изменится, если в нашем примере, приведенном в конце раздела 27.3, мы зададим каждый промежуточный узел с параметром
-G
вместо
-g
?
2. Размер буфера, указываемый в качестве аргумента функции
setsockopt
для параметра сокета
IP_OPTIONS
, должен быть кратен 4 байтам. Что бы нам пришлось делать, если бы мы не поместили параметр NOP в начало буфера, как показано на рис. 27.1?
3. Каким образом программа
ping
получает маршрут от отправителя, когда используется параметр IP Record Route (запись маршрута), описанный в разделе 7.3 [128]?
4. Почему в примере кода для сервера
rlogind
, приведенном в конце раздела 27.3, который предназначен для удаления полученного маршрута от отправителя, дескриптор сокета (первый аргумент функций
getsockopt
и
setsockopt
) имеет нулевое значение?