UNIX: разработка сетевых приложений
Чтобы задать класс трафика для пакета, нужно отправить вспомогательные данные вместе с этим пакетом. Чтобы задать класс трафика для всех пакетов, отправляемых через сокет, необходимо использовать параметр сокета
(раздел 27.7). Класс трафика для принятого пакета возвращается функциейIPV6_TCLASSво вспомогательных данных, только если приложение включило параметр сокетаrecvmsg.IPV6_RECVTCLASS22.9. Управление транспортной MTU IPv6
IPv6 предоставляет приложениям средства для управления механизмом обнаружения транспортной MTU (раздел 2.11). Значения по умолчанию пригодны для подавляющего большинства приложений, однако специальные программы могут настраивать процедуру обнаружения транспортной MTU так, как им нужно. Для этого имеется четыре параметра сокета.
Отправка с минимальной MTU
При работе в режиме детектирования транспортной MTU пакеты фрагментируются по MTU исходящего интерфейса или по транспортной MTU в зависимости от того, какое значение оказывается меньше. IPv6 требует минимального значения MTU 1280 байт. Это значение должно поддерживаться любой линией передачи. Фрагментация сообщений по этому минимальному значению позволяет не тратить ресурсы на обнаружение транспортной MTU (потерянные пакеты и задержки в процессе обнаружения), но зато не дает возможности отправлять большие пакеты (что более эффективно).
Минимальная MTU может использоваться приложениями двух типов. Во- первых, это приложения многоадресной передачи, которым нужно избегать порождения множества ICMP-сообщений «Message too big». Во-вторых, это приложения, выполняющие небольшие по объему транзакции с большим количеством адресатов (например, DNS). Обнаружение MTU для многоадресного сеанса может быть недостаточно выгодным, чтобы компенсировать затраты на получение и обработку миллионов ICMP-сообщений, а приложения типа DNS обычно связываются с серверами недостаточно часто, чтобы можно было рисковать утратой пакетов.
Использование минимальной MTU обеспечивается параметром сокета
. Для него определено три значения: -1 (по умолчанию) соответствует использованию минимальной MTU для многоадресных передач и обнаруженной транспортной MTU для направленных передач; 0 соответствует обнаружению транспортной MTU для всех передач; 1 означает использование минимальной MTU для всех адресатов.IPV6_USE_MIN_MTUПараметр
может быть передан и во вспомогательных данных. В этом случае элементIPV6_USE_MIN_MTUструктурыcmsg_levelдолжен иметь значениеcmsghdr, элементIPPROTO_IPV6должен иметь значениеcmsg_type, а первый байт данных должен быть первым байтом четырехбайтового целочисленного значения параметра.IPV6_USE_MIN_MTUПолучение сообщений об изменении транспортной MTU
Для получения уведомлений об изменении транспортной MTU приложение может включить параметр сокета
. Этот флаг разрешает доставку транспортной MTU во вспомогательных данных каждый раз, когда эта величина меняется. Функция recvmsg в этом случае возвратит дейтаграмму нулевой длины, но со вспомогательными данными, в которых будет помещена транспортная MTU. ЭлементIPV6_RECVPATHMTUструктурыcmsg_levelбудет иметь значениеcmsghdr, элементIPPROTO_IPV6будетcmsg_type, а первый байт данных будет первым байтом структурыIPV6_PATHMTU. Эта структура содержит адрес узла, для которого изменилась транспортная MTU, и новое значение этой величины в байтах.iр6_mtuinfostruct ip6_mtuinfo {struct sockaddr_in6 ip6m_addr; /* адрес узла */uint32_t ip6m_mtu; /* транспортная MTUв порядке байтов узла */};Эта структура определяется включением заголовочного файла
.<netinet/in.h>Определение текущей транспортной MTU
Если приложение не отслеживало изменения MTU при помощи параметра
, оно может определить текущее значение транспортной MTU присоединенного сокета при помощи параметраIPV6_RECVPATHMTU. Этот параметр доступен только для чтения и возвращает он структуруIPV6_PATHMTU(см. выше), в которой хранится текущее значение MTU. Если значение еще не было определено, возвращается значение MTU по умолчанию для исходящего интерфейса. Значение адреса из структурыip6_mtuinfoв данном случае не определено.ip6_mtuinfoОтключение фрагментации
По умолчанию стек IPv6 фрагментирует исходящие пакеты по транспортной MTU. Приложениям типа
автоматическая фрагментация не нужна, потому что им нужно иметь возможность самостоятельно определять транспортную MTU. Параметр сокетаtracerouteиспользуется для отключения автоматической фрагментации: значение 0 (по умолчанию) разрешает фрагментацию, тогда как значение 1 отключает ее.IPV6_DONTFRAGКогда автоматическая фрагментация отключена, вызов send со слишком большим пакетом может возвратить ошибку
, но это не является обязательным. Единственным способом определить необходимость фрагментации пакета является использование параметра сокетаEMSGSIZE, который мы описали выше.IPV6_RECVPATHMTUПараметр
может передаваться и во вспомогательных данных. При этом элементIPV6_DONTFRAGструктурыcmsg_levelдолжен иметь значениеcmsghdr, а элементIPPROTO_IPV6должен иметь значениеcmsg_type. Первый байт данных должен быть первым байтом четырехбайтового целого.IPV6_DONTFRAG22.10. Резюме
Существуют приложения, которым требуется знать IP-адрес получателя дейтаграммы UDP и интерфейс, на котором была получена эта дейтаграмма. Чтобы получать эту информацию в виде вспомогательных данных для каждой дейтаграммы, можно установить параметры сокета
иIP_RECVDSTADDR. Аналогичная информация вместе с предельным значением количества транзитных узлов полученной дейтаграммы для сокетов IPv6 становится доступна при включении параметра сокетаIP_RFCVIF.IPV6_PKTINFOНесмотря на множество полезных свойств, предоставляемых протоколом TCP и отсутствующих в UDP, существуют ситуации, когда следует отдать предпочтение UDP. UDP должен использоваться для широковещательной или многоадресной передачи. UDP может использоваться в простых сценариях «запрос-ответ», но тогда приложение должно само обеспечить некоторую функциональность, повышающую надежность протокола UDP. UDP не следует использовать для передачи большого количества данных.