Вывод UDP
Системный вызов, отправляющий данные, достигает UDP в виде вызова процедуры udp_send(), которая принимает цепочку mbuf, содержащих данные для дейтаграммы. Если вызов предоставил адрес назначения, он также передается, в противном случае используется адрес из предшествующего вызова connect.
Фактическая операция по отправке осуществляется udpoutput():
static int udp_output(struct inpcb *inp,
struct mbuf *msg,
struct mbuf *addr,
struct mbuf *control,
struct thread *td);
где inp является управляющим блоком протокола IPv4, msg является цепочкой mbuf, содержащих данные для отправки, addr является необязательным mbuf, содержащим адрес назначения, a td является указателем на структуру потока. Структуры потока используются внутри сетевого стека для идентификации отправителя пакета, поэтому они используются лишь с процедурами вывода.
Любые вспомогательные данные в control отбрасываются. Адрес назначения, возможно, определен предварительно с помощью вызова connect; в противном случае он должен быть предоставлен в вызове отправки.
UDP просто добавляет свой собственный заголовок, заполняет поля заголовка UDP и поля прототипа IP-заголовка и вычисляет контрольную сумму, прежде чем передать пакет модулю IP для вывода:
int ip_output( struct mbuf *msg,struct mbuf *opt,
struct route *ro,
int flags,
struct ip_moptions *imo,
struct inpcb *inp);
Вызов выходной процедуры IP более сложный, чем UDP, поскольку процедуре IP требуется указать больше информации о конечной точке, с которой она взаимодействует. Параметр msg указывает сообщение, которое должно быть отправлено, а параметр opt может определять список опций IP, которые должны быть помещены в заголовок IP пакета.
Для многоадресных рассылок параметр imo может ссылаться на опции многоадресной рассылки, такие, как выбор интерфейса и числа транзитных участков для групповых пакетов. Опции IP можно установить для сокета с помощью системного вызова setsockopt, указав уровень протокола IP и опцию IPOPTIONS. Эти опции хранятся в отдельном mbuf, а указатель на этот mbuf хранится в управляющем блоке протокола для сокета. Указатель на опции передается ip_output() с каждым отправляемым пакетом.
Параметр го является необязательным, процедура udp_output() передает в качестве его значения NULL, так что маршрут для пакета будет определять IP. Параметр flags определяет, разрешено ли пользователю передавать широковещательное сообщение и должна ли быть пропущена маршрутизация для отправляемого пакета.
Флаг широковещания может быть неуместным, если нижележащее оборудование не поддерживает широковещательные передачи. Флаги также указывают, включает ли пакет псевдозаголовок IP или полностью инициализированный IP-заголовок, как в случае пересылки IP пакетов.
Ввод UDP
Все транспортные протоколы Интернета, расположенные непосредственно поверх IP, используют следующее соглашение по вызову при получении пакетов от IP:
(void) (*pr_input)( struct mbuf *m, int off);
Каждая переданная цепочка mbuf является отдельным пакетом для обработки блока протокола.
Пакет включает IP-заголовок вместо псевдозаголовка, а размер IP-заголовка передается в качестве смещения во втором параметре. Входная процедура UDP udp_input() является типичной входной процедурой протокола. Она сначала проверяет, что длина пакета по крайней мере равна размеру заголовков IP плюс UDP, и использует т_pullup() для того, чтобы сделать заголовки непрерывными. Затем процедура udpinput() проверяет, что пакет имеет правильный размер, и вычисляет контрольную сумму для данных в пакете.
Если любой из этих тестов завершается ошибкой, пакет уничтожается, а число ошибок увеличивается. Потом обрабатываются все вопросы многоадресной рассылки. В конечном счете in_pcblookup() находит управляющий блок протокола для сокета, который должен получить данные, используя адреса и номера портов в пакете. Может быть несколько управляющих блоков протокола с одним и тем же номером порта, но различными локальными или удаленными адресами; в таком случае выбирается управляющий блок, больше всего подходящий.
Лучше всего подходит точное соответствие, но, если такого нет, подойдет сокет с правильным номером локального порта, но с неуказанными локальным адресом, номером удаленного порта или удаленного адреса. Таким образом, управляющий блок с неуказанным локальным или удаленным адресами действует в качестве группового (wildcard), получающего пакеты для своего порта, если не найдено точного совпадения. Если управляющий блок найден, данные и адрес, откуда был получен пакет, помещаются в приемный буфер указанного сокета с помощью udp_append(). Если адрес назначения является адресом групповой рассылки, копии пакета доставляются каждому сокету с подходящими адресами.
В противном случае, если получатель не найден и если пакет не имеет широковещательного или группового адреса, отправителю дейтаграммы посылается сообщение ICMP об ошибке недоступности порта. Это сообщение об ошибке обычно не имеет никакого эффекта, поскольку отправитель чаще всегосоединяется с этим местом назначения лишь временно и уничтожает связь до того, как новый ввод обрабатывается. Однако, если отправитель по-прежнему имеет полностью определенную связь, он может получить уведомление об ошибке.
- 16/01/2010 11:03 - Процедура пересылки IP-пакетов
- 16/01/2010 10:58 - Процедура ввода IPv4. Входная процедура.
- 16/01/2010 10:46 - Размер пакета IP. Выходная процедура IP.
- 16/01/2010 10:40 - Протокол Интернета IP (ШЗ)
- 15/01/2010 17:34 - Управляющие операции
- 14/01/2010 18:56 - UDP. Протокол пользовательских дейтаграмм
- 14/01/2010 11:41 - Управляющие блоки протоколов
- 14/01/2010 09:55 - Порты и связи Интернета
- 14/01/2010 09:39 - Многоадресная рассылка Интернета. Setsockopt
- 14/01/2010 09:29 - Широковещательные адреса