UNIX: разработка сетевых приложений
Шрифт:
При вызове функции
В Беркли-ядрах полученный маршрут от отправителя, так же как и другие параметры 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 в случае жесткой маршрутизации), так как при проходе дейтаграммы через каждый из перечисленных в списке узлов происходит замена указанного адреса на адрес интерфейса для исходящих дейтаграмм. Это позволяет получателю дейтаграммы обратить полученный список, превратив его в маршрут, по которому будет послан ответ отправителю. Примеры этих двух маршрутов от отправителя вместе с соответствующим выводом программы
Маршрут от отправителя мы определяем как массив адресов IPv4, которому предшествуют три однобайтовых поля, как показано на рис. 27.1. Это формат буфера, который передается функции
Рис. 27.1.
Перед параметром маршрута от отправителя мы поместили параметр NOP (нет действий), чтобы все IP-адреса были выровнены по 4-байтовой границе. Это не обязательно, но желательно, поскольку в результате мы выравниваем адреса, не расходуя дополнительно лишней памяти (все IP-параметры обычно выравниваются, чтобы в итоге занимать место, кратное 4 байтам).
На рис. 27.1 показано, что маршрут состоит из 10 адресов, но первый приведенный адрес удаляется из параметра маршрута от отправителя и становится адресом получателя, когда дейтаграмма IP покидает узел отправителя. Хотя в 40-байтовом пространстве, отведенном под данный параметр IP, хватает места только для 9 адресов (не забудьте о 3-байтовом заголовке параметра, который мы вскоре опишем), фактически в заголовке IPv4 у нас имеется 10 IP-адресов, так как к 9 адресам узлов добавляется адрес получателя.
Поле
Теперь мы переходим к определению трех функций, с помощью которых мы инициализируем, создаем и обрабатываем параметр маршрута от отправителя. Наши функции предназначены для работы только с этим параметром. Хотя в принципе возможно объединить параметр маршрута от отправителя с другими параметрами IP (такими как параметр извещения маршрутизатора), но на практике параметры редко комбинируются. В листинге 27.1 [1] приведена функция
1
Все исходные коды программ, опубликованные в этой книге, вы можете найти по адресу http://www.piter.com.
Листинг 27.1. Функция inet_srcrt_init: инициализация перед записью маршрута от отправителя