Содержание
Обзор: создание IPC-каналов
Есть два способа создания IPC-каналов: статический и динамический.
Статическое создание IPC-каналов проще в реализации, поскольку для него можно использовать init-описание.
Динамическое создание IPC-каналов позволяет изменять топологию взаимодействия процессов "на лету". Это требуется, если неизвестно, какой именно сервер содержит службу, необходимую клиенту. Например, может быть неизвестно, на какой именно накопитель нужно будет записывать данные.
Статическое создание IPC-канала
Статический способ имеет следующие особенности:
- клиент и сервер находятся в остановленном состоянии в момент создания IPC-канала;
- создание инициируются родительским процессом, запускающим клиента и сервера (обычно это Einit);
- созданный IPC-канал невозможно удалить;
- чтобы получить IPC-дескриптор и идентификатор службы (riid) после создания IPC-канала, клиент и сервер должны использовать интерфейс локатора сервисов (
coresrv/sl/sl_api.h
).
Динамическое создание IPC-канала
Динамический способ имеет следующие особенности:
- клиент и сервер уже запущены в момент создания IPC-канала;
- создание инициируются совместно клиентом и сервером;
- созданный IPC-канал может быть удален;
- клиент и сервер получают IPC-дескриптор и идентификатор службы (riid) сразу после успешного создания IPC-канала.
Создание IPC-каналов с помощью init.yaml
Здесь собраны init-описания, демонстрирующие особенности создания IPC-каналов. Примеры задания свойств и аргументов процессов через init-описания разбираются в отдельной статье.
В примерах в составе KasperskyOS Community Edition может использоваться формат init-описания с макросами (init.yaml.in
).
Файл с init-описанием обычно называется init.yaml
, хотя может иметь любое имя.
Соединение и запуск процесса-клиента и процесса-сервера
В следующем примере будут запущены два процесса: класса Client
и класса Server
. Имена процессов не указаны, поэтому они будут совпадать с именами классов процессов. Имена исполняемых файлов также не указаны, они также будут совпадать с именами классов. Процессы будут соединены IPC-каналом с именем server_connection
.
init.yaml
entities:
- name: Client
connections:
- target: Server
id: server_connection
- name: Server
Динамическое создание IPC-каналов
При динамическом создании IPC-канала используются функции:
- интерфейса сервера имен (Name Server);
- интерфейса менеджера соединений (Connection Manager).
Динамическое создание IPC-канала осуществляется по следующему сценарию:
- Запускаются процессы: клиент, сервер и сервер имен.
- Сервер подключается к серверу имен с помощью вызова
NsCreate()
и публикует имя сервера, имя интерфейса и имя службы с помощью вызоваNsPublishService()
. - Клиент подключается к серверу имен с помощью вызова
NsCreate()
и выполняет поиск имени сервера и имени службы по имени интерфейса с помощью вызоваNsEnumServices()
. - Клиент запрашивает доступ к службе с помощью вызова
KnCmConnect()
, передавая в качестве аргументов найденные имя сервера и имя службы. - Сервер вызывает функцию
KnCmListen()
для проверки наличия запросов на доступ к службе. - Сервер принимает запрос клиента на доступ к службе с помощью вызова
KnCmAccept()
, передавая в качестве аргументов имя клиента и имя службы, которые получены при вызовеKnCmListen()
.
Пункты 2 и 3 могут быть опущены, если клиент заранее знает имя сервера и имя службы.
Сервер может снимать с публикации на сервере имен ранее опубликованные службы с помощью вызова NsUnPublishService()
.
Сервер может отклонять запросы доступа к службам с помощью вызова KnCmDrop()
.
Для использования сервера имен политика безопасности решения должна разрешать взаимодействие процесса класса kl.core.NameServer
и процессами, между которыми необходимо динамически создавать IPC-каналы.