UNIX: разработка сетевых приложений
2. EOL (end-of-list — конец списка параметров). Этот однобайтовый параметр обозначает конец списка параметров. Поскольку суммарный размер параметров IP должен быть кратным 4 байтам, после последнего параметра добавляются байты EOL.
3. LSRR (Loose Source and Record Route — гибкая маршрутизация от отправителя с записью) (см. раздел 8.5 [111]). Пример использования этого параметра мы вскоре продемонстрируем.
4. SSRR (Strict Source and Record Route — жесткая маршрутизация от отправителя с записью) (см. раздел 8.5 [111]). Пример использования этого параметра мы также вскоре продемонстрируем.
5. Отметка времени (timestamp) (см. раздел 7.4 [111]).
6. Запись маршрута (record route) (см. раздел 7.3 [111]).
7. Основной параметр обеспечения безопасности (устаревший параметр) (basic security).
8. Расширенный параметр обеспечения безопасности (устаревший параметр) (extended security).
9. Идентификатор потока (устаревший параметр) (stream identifier).
10. Извещение маршрутизатора (router alert). Этот параметр описан в RFC 2113 [60]. Он включается в дейтаграмму IP, для того чтобы все пересылающие эту дейтаграмму маршрутизаторы обрабатывали ее содержимое.
В главе 9 книги [128] приводится более подробное рассмотрение первых шести параметров, а в указанных далее разделах [111] имеются примеры их использования.
Функции
иgetsockopt(с аргументом level, равнымsetsockopt, а аргументомIPPROTO_IP—optname) предназначены соответственно для получения и установки параметров IP. Четвертый аргумент функцийIP_OPTIONSиgetsockopt— это указатель на буфер (размер которого не превосходит 44 байт), а пятый аргумент — это размер буфера. Причина, по которой размер буфера может на 4 байт превосходить максимальный суммарный размер параметров, заключается в способе обработки параметров маршрута от отправителя, как мы вскоре увидим. Все остальные параметры помещаются в буфер именно в том виде, в котором они потом упаковываются в заголовок дейтаграммы.setsockoptКогда параметры IP задаются с использованием функции
, указанные параметры включаются во все дейтаграммы, отсылаемые с данного сокета. Этот принцип работает для сокетов TCP, UDP и для символьных сокетов. Для отмены какого-либо параметра следует вызвать функциюsetsockoptи задать либо пустой указатель в качестве четвертого аргумента, либо нулевое значение в качестве пятого аргумента (длина).setsockoptПРИМЕЧАНИЕУстановка параметров IP для символьного сокета IP работает не во всех реализациях, если уже установлен параметр IP_HDRINCL (который мы обсудим в последующих главах). Многие Беркли-реализации не отсылают параметры, установленные с помощью IP_OPTIONS, если включен параметр IP_HDRINCL, так как приложение может устанавливать собственные параметры в формируемом им заголовке IP [128, с. 1056-1057]. В других системах (например, в FreeBSD) приложение может задавать свои параметры IP, либо используя параметр сокета IP_OPTIONS, либо установив параметр IP_HDRINCL и включив требуемые параметры в создаваемый им заголовок IP, но одновременное применение обоих этих способов не допускается.
При вызове функции
для получения параметров IP присоединенного сокета TCP, созданного функциейgetsockopt, возвращается лишь обращенный параметр маршрута от отправителя, полученный вместе с клиентским сегментом SYN на прослушиваемом сокете [128, с. 931]. TCP автоматически обращает маршрут от отправителя, поскольку маршрут, указанный клиентом, — это маршрут от клиента к серверу, а сервер должен использовать для отсылаемых им дейтаграмм обратный маршрут. Если вместе с сегментом SYN не был получен маршрут от отправителя, то значение пятого аргумента (этот аргумент типа «значение-результат», как было указано ранее, задает длину буфера) при завершении функцииacceptбудет равно нулю. Для прочих сокетов TCP, всех сокетов UDP и всех символьных сокетов IP при вызове функцииgetsockoptвы просто получите копию тех параметров IP, которые были установлены для этих сокетов с помощью функцииgetsockopt. Заметим, что для символьных сокетов IP полученный заголовок IP, включая все параметры IP, всегда возвращается всеми входными функциями, поэтому полученные параметры IP всегда доступны.setsockoptПРИМЕЧАНИЕВ Беркли-ядрах полученный маршрут от отправителя, так же как и другие параметры IP, никогда не возвращается для сокетов UDP. Показанный на с. 775 [128] код, предназначенный для получения параметров IP, существовал со времен 4.3BSD Reno, но так как он не работал, его всегда приходилось превращать в комментарий. Таким образом, для сокетов UDP невозможно использовать обращенный маршрут от отправителя полученной дейтаграммы, чтобы отослать ответ.
27.3. Параметры маршрута от отправителя IPv4
Маршрут от отправителя (source route) — это список IP-адресов, указанных отправителем дейтаграммы IP. Если маршрут является жестким (строгим, strict), то дейтаграмма должна передаваться только между указанными узлами и пройти их все. Иными словами, все узлы, перечисленные в маршруте от отправителя, должны быть соседними друг для друга. Но если маршрут является свободным, или гибким (loose), дейтаграмма должна пройти все перечисленные в нем узлы, но может при этом пройти и еще какие-то узлы, не входящие в список.
ПРИМЕЧАНИЕМаршрутизация от отправителя (source routing) в IPv4 является предметом споров и сомнений. В [20] пропагандируется отказ от поддержки этой функции на всех маршрутизаторах, и многие организации и провайдеры действительно следуют этому принципу. Один из наиболее разумных способов использования маршрутизации от отправителя — это обнаружение с помощью программы traceroute асимметричных маршрутов, как показано на с. 108–109 [111], но в настоящее время даже этот способ становится непопулярен. Тем не менее определение и получение маршрута от отправителя — это часть API сокетов, и поэтому заслуживает описания.
Параметры IPv4, связанные с маршрутизацией от отправителя, называются параметрами маршрутизации от отправителя с записью (Loose Source and Record Routes — LSRR в случае свободной маршрутизации и Strict Source and Record Routes — SSRR в случае жесткой маршрутизации), так как при проходе дейтаграммы через каждый из перечисленных в списке узлов происходит замена указанного адреса на адрес интерфейса для исходящих дейтаграмм. Это позволяет получателю дейтаграммы обратить полученный список, превратив его в маршрут, по которому будет послан ответ отправителю. Примеры этих двух маршрутов от отправителя вместе с соответствующим выводом программы
, приведены в разделе 8.5 книги [111].tcpdumpМаршрут от отправителя мы определяем как массив адресов IPv4, которому предшествуют три однобайтовых поля, как показано на рис. 27.1. Это формат буфера, который передается функции
.setsockoptРис. 27.1. Передача маршрута от отправителя ядру
Перед параметром маршрута от отправителя мы поместили параметр NOP (нет действий), чтобы все IP-адреса были выровнены по 4-байтовой границе. Это не обязательно, но желательно, поскольку в результате мы выравниваем адреса, не расходуя дополнительно лишней памяти (все IP-параметры обычно выравниваются, чтобы в итоге занимать место, кратное 4 байтам).
