Вместо того чтобы отсылать эти параметры при каждом вызове функции 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
) имеет нулевое значение?