}
}
Подобным образом реализовано большинство функций TLI. Заметим, что в конкретном случае использования транспортного протокола TCP прием и передача данных осуществляются в виде потока, не содержащего каких-либо логических записей. В этом случае не требуется формирование примитивов типа T_DATA_REQ
и T_DATA_IND
. В то же время, для передачи и получения экстренных данных будут использованы примитивы T_EXDATA_REQ
и T_EXDATA_IND
. При использовании протокола UDP все данные будут передаваться с помощью примитивов T_UNITDATA_REQ
и T_UNITDATA_IND
.
Описанная реализация программного интерфейса TLI имеет один существенный недостаток — операции функций не являются атомарными. Другими словами, выполнение функции t_connect(3N) может быть прервано другими процессами, которые могут также связываться с удаленным узлом. Это возможно, поскольку выполнение значительной части операций происходит в режиме задачи. Если для функции t_connect(3N) нарушение атомарности допустимо, то ряд функций, таких, например, как связывание ( t_bind(3N) ), получение информации ( t_open(3N) , t_getinfo(3N) ) и установка или получение опций протокола ( t_optmgmt(3N) ) должны быть защищены от возможного нарушения целостности данных по причине прерывания операции. Единственным способом гарантировать атомарность является перевод выполнения критических участков (например, между отправлением примитива и получением подтверждения от поставщика транспортных услуг) в режим ядра. Для этого подсистема STREAMS предлагает механизм обмена управляющими командами с помощью вызова ioctl(2) .
Однако с помощью ioctl(2) , как было показано в разделе "Подсистема STREAMS" главы 5, можно формировать лишь сообщения типа M_IOCTL
. Для преобразования этих сообщений в примитивы TPI служит дополнительный модуль timod(7M) , встраиваемый в поток между головным и транспортным модулями. На рис. 6.33 показано местоположение модуля timod(7M) и схематически отображены его функции.
Рис. 6.33. Архитектура доступа к транспортным услугам
Для всех сообщений STREAMS, за исключением сообщений M_IOCTL
, которые генерируются головным модулем в ответ на системный вызов ioctl(fd, I_STR, ...)
, модуль timod(7M) является прозрачным, т.е. он просто передает эти сообщения следующему модулю вниз по потоку без какой-либо обработки. Несколько сообщений M_IOCTL
обрабатываются модулем и преобразуются в соответствующие примитивы TPI.
При этом вызов ioctl(2) имеет следующий формат:
#include
struct strioctl my_strioctl
...
strioctl.ic_cmd = cmd;
strioctl.ic_timeout = INFTIM;
strioctl.ic_len = size;
strioctl.ic_dp = (char*)buf;
ioctl(fd, I_STR, &my_strioctl);
При вызове ioctl(2) поле size
устанавливается равным размеру соответствующего примитива TPI, определенного полем cmd
и расположенного в буфере buf
. При возврате из функции поле size
содержит размер примитива, возвращенного поставщиком транспортных услуг и расположенного в буфере buf.
Модуль timod(7M) служит для обработки следующих команд cmd:
Значение cmd |
Обработка модулем timod(7M) |
TI_BIND |
Команда преобразуется в примитив T_BIND_REQ . При успешном завершении функции ioctl(2) в буфере buf находится примитив T_BIND_ACK . |
TI_UNBIND |
Команда преобразуется в примитив T_UNBIND_REQ . При успешном завершении функции ioctl(2) в буфере buf находится примитив T_OK_ACK . |
TI_GETINFO |
Команда преобразуется в примитив T_INFO_REQ . При успешном завершении функции ioctl(2) в буфере buf находится примитив T_INFO_ACK . |
TI_OPTMGMT |
Команда преобразуется в примитив T_OPTMT_REQ . При успешном завершении функции ioctl(2) в буфере buf находится примитив T_OPTMGMT_ACK . |
DLPI определяет интерфейс между протоколами уровня канала данных (data link layer) модели OSI, называемыми поставщиками услуг уровня канала данных и протоколами сетевого уровня, называемыми пользователями услуг уровня канала данных. В качестве примера пользователей услуг уровня канала данных можно привести такие протоколы, как IP, IPX или CLNS. С другой стороны, поставщик услуг уровня канала данных непосредственно взаимодействует с различными сетевыми устройствами, обеспечивающими передачу данных по сетям различной архитектуры (например, Ethernet, FDDI или ATM) и использующими различные физические среды передачи.
Читать дальше