KasperskyOS Community Edition 1.2

Файловые системы и сеть

В KasperskyOS работа с файловыми системами и сетью выполняется через отдельную системную программу, реализующую виртуальную файловую систему (англ. Virtual File System, VFS).

В составе SDK компонент VFS представлен набором исполняемых файлов, библиотек, файлов формальной спецификации и заголовочных файлов. Подробнее см. раздел "Состав компонента VFS".

Основной сценарий взаимодействия с системной программой VFS происходит следующим образом:

  1. Прикладная программа соединяется IPC-каналом с системной программой VFS и при сборке компонуется с клиентской библиотекой компонента VFS.
  2. В прикладном коде POSIX-вызовы для работы с файловыми системами и сетью преобразуются в вызовы функций клиентской библиотеки.

    Ввод и вывод в файловые дескрипторы для стандартных потоков ввода-вывода (stdin, stdout и stderr) также преобразуется в обращения к VFS. Если прикладная программа не скомпонована с клиентской библиотекой компонента VFS, то вывод в stdout невозможен. В таком случае возможен только вывод в стандартный поток ошибок (stderr), который в этом случае осуществляется без использования VFS через специальные методы ядра KasperskyOS.

  3. Клиентская библиотека выполняет IPC-запросы к системной программе VFS.
  4. Системная программа VFS принимает IPC-запросы и вызывает соответствующие реализации файловых систем (которые, в свою очередь могут выполнять IPC-запросы к драйверам устройств) или сетевые драйверы.
  5. После обработки запроса, системная программа VFS выполняет ответы на IPC-запросы прикладной программы.

Использование нескольких программ VFS

В решение можно добавить несколько копий системной программы VFS, разделив таким образом информационные потоки разных системных и прикладных программ. Также можно разделить информационные потоки в рамках одной прикладной программы. Подробнее см. "Разделение информационных потоков с помощью VFS-бэкендов".

Включение функциональности VFS в прикладную программу

Функциональность компонента VFS можно полностью включить в прикладную программу, избавляясь при этом от необходимости передавать каждый запрос через IPC. Подробнее см. "Включение функциональности VFS в программу".

При этом использование функциональности VFS по IPC позволяет разработчику решения:

  • контролировать вызовы методов для работы с сетью и файловыми системами с помощью политики безопасности решения;
  • соединить несколько клиентских программ с одной программой VFS;
  • соединить одну клиентскую программу с двумя программами VFS для раздельной работы с сетью и файловыми системами.

В этом разделе

Состав компонента VFS

Создание IPC-канала до VFS

Включение функциональности VFS в программу

Обзор: параметры запуска и переменные окружения VFS

Монтирование файловых систем при запуске VFS

Разделение информационных потоков с помощью VFS-бэкендов

Создание VFS-бэкенда

Динамическая настройка сетевого стека

В начало
[Topic sc_filesystems_and_net]

Состав компонента VFS

Компонент VFS реализует виртуальную файловую систему. В составе KasperskyOS SDK компонент VFS представлен набором исполняемых файлов, библиотек, файлов формальной спецификации и заголовочных файлов, позволяющих использовать файловые системы и/или сетевой стек.

Библиотеки VFS

CMake-пакет vfs содержит следующие библиотеки:

  • vfs_fs – содержит реализации файловых систем devfs, ramfs и ROMFS, а также позволяет добавить в VFS реализации других файловых систем.
  • vfs_net – содержит реализацию файловой системы devfs и сетевого стека.
  • vfs_imp – содержит библиотеки vfs_fs и vfs_net.
  • vfs_remote – клиентская транспортная библиотека, которая преобразует локальные вызовы в IPC-запросы к VFS и принимает IPC-ответы.
  • vfs_server – серверная транспортная библиотека VFS, которая принимает IPC-запросы, преобразует их в локальные вызовы и отправляет IPC-ответы.
  • vfs_local – используется для включения функциональности VFS в программу.

Исполняемые файлы VFS

CMake-пакет precompiled_vfs содержит следующие исполняемые файлы:

  • VfsRamFs;
  • VfsSdCardFs;
  • VfsNet.

Исполняемые файлы VfsRamFs и VfsSdCardFs включают в себя библиотеки vfs_server, vfs_fs, vfat и lwext4. Исполняемый файл VfsNet включает в себя библиотеки vfs_server и vfs_imp.

Каждый из этих исполняемых файлов имеет собственные значения параметров запуска и переменных окружения по умолчанию.

Файлы формальной спецификации и заголовочные файлы VFS

В директории sysroot-*-kos/include/kl из состава KasperskyOS SDK находятся следующие файлы VFS:

  • файлы формальной спецификации VfsRamFs.edl, VfsSdCardFs.edl, VfsNet.edl и VfsEntity.edl и сгенерированные из них заголовочные файлы;
  • файл формальной спецификации Vfs.cdl и сгенерированный из него заголовочный файл Vfs.cdl.h;
  • файлы формальной спецификации Vfs*.idl и сгенерированные из них заголовочные файлы.

API библиотеки libc, поддерживаемый VFS

Функциональность VFS доступна программам через API, предоставляемый библиотекой libc.

Функции, реализуемые библиотеками vfs_fs и vfs_net, приведены в таблицах ниже. Символом * отмечены функции, которые включаются в библиотеку vfs_fs опционально (в зависимости от параметров сборки библиотеки).

Функции, реализуемые библиотекой vfs_fs

mount()

unlink()

ftruncate()

lsetxattr()*

umount()

rmdir()

chdir()

fsetxattr()*

open()

mkdir()

fchdir()

getxattr()*

openat()

mkdirat()

chmod()

lgetxattr()*

read()

fcntl()

fchmod()

fgetxattr()*

readv()

statvfs()

fchmodat()

listxattr()*

write()

fstatvfs()

chroot()

llistxattr()*

writev()

getvfsstat()

fsync()

flistxattr()*

stat()

pipe()

fdatasync()

removexattr()*

lstat()

futimens()

pread()

lremovexattr()*

fstat()

utimensat()

pwrite()

fremovexattr()*

fstatat()

link()

sendfile()

acl_set_file()*

lseek()

linkat()

getdents()

acl_get_file()*

close()

symlink()

sync()

acl_delete_def_file()*

rename()

symlinkat()

ioctl()

 

renameat()

unlinkat()

setxattr()*

 

Функции, реализуемые библиотекой vfs_net

read()

bind()

getsockname()

recvfrom()

readv()

listen()

gethostbyname()

recvmsg()

write()

connect()

getnetbyaddr()

send()

writev()

accept()

getnetbyname()

sendto()

fstat()

poll()

getnetent()

sendmsg()

close()

shutdown()

setnetent()

ioctl()

fcntl()

getnameinfo()

endnetent()

sysctl()

fstatvfs()

getaddrinfo()

getprotobyname()

 

pipe()

freeaddrinfo()

getprotobynumber()

 

futimens()

getifaddrs()

getsockopt()

 

socket()

freeifaddrs()

setsockopt()

 

socketpair()

getpeername()

recv()

 

Если в VFS нет реализации вызванной функции, возвращается код ошибки EIO.

В начало
[Topic vfs_overview]

Создание IPC-канала до VFS

В этом примере процесс Client использует файловые системы и сетевой стек, а процесс VfsFsnet обрабатывает IPC-запросы процесса Client, связанные с использованием файловых систем и сетевого стека. Такой подход используется в тех случаях, когда не требуется разделение информационных потоков, связанных с файловыми системами и сетевым стеком.

Имя IPC-канала должно задаваться макросом _VFS_CONNECTION_ID, определенным в заголовочном файле sysroot-*-kos/include/vfs/defs.h из состава KasperskyOS SDK.

Init-описание примера:

init.yaml

- name: Client connections: - target: VfsFsnet id: {var: _VFS_CONNECTION_ID, include: vfs/defs.h} - name: VfsFsnet
В начало
[Topic client_and_vfs_ipc_channel]

Включение функциональности VFS в программу

В этом примере программа Client включает функциональность программы VFS для работы с сетевым стеком (см. рис. ниже).

Библиотеки компонента VFS в составе программы

Выполняется компиляция файла реализации client.c и компоновка с библиотеками vfs_local, vfs_implementation и dnet_implementation:

CMakeLists.txt

project (client) include (platform/nk) # Установка флагов компиляции project_header_default ("STANDARD_GNU_11:YES" "STRICT_WARNINGS:NO") # Генерация файла Client.edl.h nk_build_edl_files (client_edl_files NK_MODULE "client" EDL "${CMAKE_SOURCE_DIR}/resources/edl/Client.edl") add_executable (Client "src/client.c") add_dependencies (Client client_edl_files) # Компоновка с библиотеками VFS target_link_libraries (Client ${vfs_LOCAL_LIB} ${vfs_IMPLEMENTATION_LIB} ${dnet_IMPLEMENTATION_LIB}

Если бы программа Client использовала файловые системы, то нужно было бы выполнить компоновку с библиотеками vfs_local и vfs_fs, а также с библиотеками реализации этих файловых систем. Кроме того, нужно было бы добавить в решение драйвер блочного устройства.

В начало
[Topic client_and_vfs_linked]

Обзор: параметры запуска и переменные окружения VFS

Параметры запуска программы VFS

  • -l <запись в формате fstab>

    Параметр запуска -l монтирует заданную файловую систему.

  • -f <путь к файлу fstab>

    Параметр -f монтирует файловые системы, указанные в файле fstab. Если переменная окружения UNMAP_ROMFS не определена, то поиск файла fstab будет выполнен в ROMFS-образе. Если переменная окружения UNMAP_ROMFS определена, то поиск файла fstab будет выполнен в файловой системе, заданной через переменную окружения ROOTFS.

Примеры использования параметров запуска программы VFS

Переменные окружения программы VFS

  • UNMAP_ROMFS

    Если переменная окружения UNMAP_ROMFS определена, то ROMFS-образ будет удален из памяти. Это позволяет сэкономить память, а также при использовании параметра запуска -f дает возможность выполнить поиск файла fstab не в ROMFS-образе, а в файловой системе, заданной через переменную окружения ROOTFS.

    Пример использования переменной окружения UNMAP_ROMFS

  • ROOTFS = <запись в формате fstab>

    Переменная окружения ROOTFS позволяет монтировать заданную файловую систему в корневую директорию. При использовании параметра запуска -f комбинация переменных окружения ROOTFS и UNMAP_ROMFS дает возможность выполнить поиск файла fstab не в ROMFS-образе, а в файловой системе, заданной через переменную окружения ROOTFS.

    Пример использования переменной окружения ROOTFS

  • VFS_CLIENT_MAX_THREADS

    Переменная окружения VFS_CLIENT_MAX_THREADS позволяет переопределить параметр конфигурирования SDK VFS_CLIENT_MAX_THREADS.

  • _VFS_NETWORK_BACKEND=<имя VFS-бэкенда>:<имя IPC-канала до процесса VFS>

    Переменная окружения _VFS_NETWORK_BACKEND задает VFS-бэкенд для работы с сетевым стеком. Можно указать имя стандартного VFS-бэкенда: client (для программы, исполняющейся в контексте клиентского процесса), server (для программы VFS, исполняющейся в контексте серверного процесса) или local, а также имя пользовательского VFS-бэкенда. Если используется VFS-бэкенд local, то имя IPC-канала не указывается (_VFS_NETWORK_BACKEND=local:). Может быть указано более одного IPC-канала через запятую.

  • _VFS_FILESYSTEM_BACKEND=<имя VFS-бэкенда>:<имя IPC-канала до процесса VFS>

    Переменная окружения _VFS_FILESYSTEM_BACKEND задает VFS-бэкенд для работы с файловыми системами. Имя VFS-бэкенда и имя IPC-канала до процесса VFS задаются так же, как и в переменной окружения _VFS_NETWORK_BACKEND.

Значения по умолчания для параметров запуска и переменных окружения VFS

Для исполняемого файла VfsRamFs:

ROOTFS = ramdisk0,0 / ext4 0 VFS_FILESYSTEM_BACKEND = server:kl.VfsRamFs

Для исполняемого файла VfsSdCardFs:

ROOTFS = mmc0,0 / fat32 0 VFS_FILESYSTEM_BACKEND = server:kl.VfsSdCardFs -l nodev /tmp ramfs 0 -l nodev /var ramfs 0

Для исполняемого файла VfsNet:

VFS_NETWORK_BACKEND = server:kl.VfsNet VFS_FILESYSTEM_BACKEND = server:kl.VfsNet -l devfs /dev devfs 0
В начало
[Topic vfs_args_and_envs_overview]

Монтирование файловых систем при запуске VFS

При запуске программы VFS по умолчанию монтируется только файловая система RAMFS в корневую директорию. Если требуется монтировать другие файловые системы, это можно сделать не только с помощью вызова функции mount(), но и установив параметры запуска и переменные окружения программы VFS.

Файловые системы ROMFS и squashfs предназначены только для чтения, поэтому для монтирования этих файловых систем нужно указать параметр ro.

Использование параметра запуска -l

Одним из способов монтировать файловую систему является установка для программы VFS параметра запуска -l <запись в формате fstab>.

В этих примерах при запуске программы VFS будут монтированы файловые системы devfs и ROMFS:

init.yaml.(in)

... - name: VfsFirst args: - -l - devfs /dev devfs 0 - -l - romfs /etc romfs ro ...

CMakeLists.txt

... set_target_properties (${vfs_ENTITY} PROPERTIES EXTRA_ARGS " - -l - devfs /dev devfs 0 - -l - romfs /etc romfs ro") ...

Использование файла fstab из ROMFS-образа

При сборке решения можно добавить файл fstab в ROMFS-образ. Этот файл можно использовать для монтирования файловых систем, установив для программы VFS параметр запуска -f <путь к файлу fstab>.

В этих примерах при запуске программы VFS будут монтированы файловые системы, заданные через файл fstab, который был добавлен при сборке решения в ROMFS-образ:

init.yaml.(in)

... - name: VfsSecond args: - -f - fstab ...

CMakeLists.txt

... set_target_properties (${vfs_ENTITY} PROPERTIES EXTRA_ARGS " - -f - fstab") ...

Использование "внешнего" файла fstab

Если файл fstab находится не в ROMFS-образе, а в другой файловой системе, то для использования этого файла необходимо установить для программы VFS следующие параметры запуска и переменные окружения:

  1. ROOTFS. Эта переменная окружения позволяет монтировать в корневую директорию файловую систему, содержащую файл fstab.
  2. UNMAP_ROMFS. Если эта переменная окружения определена, то поиск файла fstab будет выполнен в файловой системе, заданной через переменную окружения ROOTFS.
  3. -f. Этот параметр запуска используется, чтобы монтировать файловые системы, указанные в файле fstab.

В этих примерах при запуске программы VFS в корневую директорию будет монтирована файловая система ext2, в которой должен находиться файл fstab по пути /etc/fstab:

init.yaml.(in)

... - name: VfsThird args: - -f - /etc/fstab env: ROOTFS: ramdisk0,0 / ext2 0 UNMAP_ROMFS: 1 ...

CMakeLists.txt

... set_target_properties (${vfs_ENTITY} PROPERTIES EXTRA_ARGS " - -f - /etc/fstab" EXTRA_ENV " ROOTFS: ramdisk0,0 / ext2 0 UNMAP_ROMFS: 1") ...
В начало
[Topic mount_on_start]

Разделение информационных потоков с помощью VFS-бэкендов

В этом примере применяется паттерн безопасной разработки, предусматривающий отделение информационных потоков, связанных с использованием файловых систем, от информационных потоков, связанных с использованием сетевого стека.

Процесс Client использует файловые системы и сетевой стек. Процесс VfsFirst обеспечивает работу с файловыми системами, а процесс VfsSecond дает возможность работать с сетевым стеком. Через переменные окружения программ, исполняющихся в контекстах процессов Client, VfsFirst и VfsSecond, заданы VFS-бэкенды, которые обеспечивают раздельное использование файловых систем и сетевого стека. В результате этого IPC-запросы процесса Client, связанные с использованием файловых систем, обрабатываются процессом VfsFirst, а IPC-запросы процесса Client, связанные с использованием сетевого стека, обрабатываются процессом VfsSecond (см. рис. ниже).

Схема взаимодействия процессов

Init-описание примера:

init.yaml

entities: - name: Client connections: - target: VfsFirst id: VFS1 - target: VfsSecond id: VFS2 env: _VFS_FILESYSTEM_BACKEND: client:VFS1 _VFS_NETWORK_BACKEND: client:VFS2 - name: VfsFirst env: _VFS_FILESYSTEM_BACKEND: server:VFS1 - name: VfsSecond env: _VFS_NETWORK_BACKEND: server:VFS2
В начало
[Topic client_and_two_vfs]

Создание VFS-бэкенда

В этом примере показано, как создать и использовать собственный VFS-бэкенд.

Процесс Client использует файловые системы fat32 и ext4. Процесс VfsFirst обеспечивает работу с файловой системой fat32, а процесс VfsSecond дает возможность работать с файловой системой ext4. Через переменные окружения программ, исполняющихся в контекстах процессов Client, VfsFirst и VfsSecond, заданы VFS-бэкенды, которые обеспечивают обработку IPC-запросов процесса Client процессом VfsFirst или VfsSecond в зависимости от того, какую файловую систему использует процесс Client. В результате этого IPC-запросы процесса Client, связанные с использованием файловой системы fat32, обрабатываются процессом VfsFirst, а IPC-запросы процесса Client, связанные с использованием файловой системы ext4, обрабатываются процессом VfsSecond (см. рис. ниже).

На стороне процесса VfsFirst файловая система fat32 монтируется в директорию /mnt1. На стороне процесса VfsSecond файловая система ext4 монтируется в директорию /mnt2. Пользовательский VFS-бэкенд custom_client, используемый на стороне процесса Client, позволяет отправлять IPC-запросы по IPC-каналу VFS1 или VFS2 в зависимости от того, начинается ли путь к файлу с /mnt1 или нет. При этом пользовательский VFS-бэкенд использует в качестве посредника стандартный VFS-бэкенд client.

Схема взаимодействия процессов

Исходный код VFS-бэкенда

Этот файл реализации содержит исходный код VFS-бэкенда custom_client, использующего стандартные VFS-бэкенды client:

backend.c

#include <vfs/vfs.h> #include <stdio.h> #include <stdlib.h> #include <platform/compiler.h> #include <pthread.h> #include <errno.h> #include <string.h> #include <getopt.h> #include <assert.h> /* Код управления файловыми дескрипторами */ #define MAX_FDS 50 struct entry { Handle handle; bool is_vfat; }; struct fd_array { struct entry entries[MAX_FDS]; int pos; pthread_rwlock_t lock; }; struct fd_array fds = { .pos = 0, .lock = PTHREAD_RWLOCK_INITIALIZER }; int insert_entry(Handle fd, bool is_vfat) { pthread_rwlock_wrlock(&fds.lock); if (fds.pos == MAX_FDS) { pthread_rwlock_unlock(&fds.lock); return -1; } fds.entries[fds.pos].handle = fd; fds.entries[fds.pos].is_vfat = is_vfat; fds.pos++; pthread_rwlock_unlock(&fds.lock); return 0; } struct entry *find_entry(Handle fd) { pthread_rwlock_rdlock(&fds.lock); for (int i = 0; i < fds.pos; i++) { if (fds.entries[i].handle == fd) { pthread_rwlock_unlock(&fds.lock); return &fds.entries[i]; } } pthread_rwlock_unlock(&fds.lock); return NULL; } /* Структура пользовательского VFS-бэкенда */ struct context { struct vfs wrapper; pthread_rwlock_t lock; struct vfs *vfs_vfat; struct vfs *vfs_ext4; }; struct context ctx = { .wrapper = { .dtor = _vfs_backend_dtor, .disconnect_all_clients = _disconnect_all_clients, .getstdin = _getstdin, .getstdout = _getstdout, .getstderr = _getstderr, .open = _open, .read = _read, .write = _write, .close = _close, } }; /* Реализация методов пользовательского VFS-бэкенда */ static bool is_vfs_vfat_path(const char *path) { char vfat_path[5] = "/mnt1"; if (memcmp(vfat_path, path, sizeof(vfat_path)) != 0) return false; return true; } static void _vfs_backend_dtor(struct vfs *vfs) { ctx.vfs_vfat->dtor(ctx.vfs_vfat); ctx.vfs_ext4->dtor(ctx.vfs_ext4); } static void _disconnect_all_clients(struct vfs *self, int *error) { (void)self; (void)error; ctx.vfs_vfat->disconnect_all_clients(ctx.vfs_vfat, error); ctx.vfs_ext4->disconnect_all_clients(ctx.vfs_ext4, error); } static Handle _getstdin(struct vfs *self, int *error) { (void)self; Handle handle = ctx.vfs_vfat->getstdin(ctx.vfs_vfat, error); if (handle != INVALID_HANDLE) { if (insert_entry(handle, true)) { *error = ENOMEM; return INVALID_HANDLE; } } return handle; } static Handle _getstdout(struct vfs *self, int *error) { (void)self; Handle handle = ctx.vfs_vfat->getstdout(ctx.vfs_vfat, error); if (handle != INVALID_HANDLE) { if (insert_entry(handle, true)) { *error = ENOMEM; return INVALID_HANDLE; } } return handle; } static Handle _getstderr(struct vfs *self, int *error) { (void)self; Handle handle = ctx.vfs_vfat->getstderr(ctx.vfs_vfat, error); if (handle != INVALID_HANDLE) { if (insert_entry(handle, true)) { *error = ENOMEM; return INVALID_HANDLE; } } return handle; } static Handle _open(struct vfs *self, const char *path, int oflag, mode_t mode, int *error) { (void)self; Handle handle; bool is_vfat = false; if (is_vfs_vfat_path(path)) { handle = ctx.vfs_vfat->open(ctx.vfs_vfat, path, oflag, mode, error); is_vfat = true; } else handle = ctx.vfs_ext4->open(ctx.vfs_ext4, path, oflag, mode, error); if (handle == INVALID_HANDLE) return INVALID_HANDLE; if (insert_entry(handle, is_vfat)) { if (is_vfat) ctx.vfs_vfat->close(ctx.vfs_vfat, handle, error); *error = ENOMEM; return INVALID_HANDLE; } return handle; } static ssize_t _read(struct vfs *self, Handle fd, void *buf, size_t count, bool *nodata, int *error) { (void)self; struct entry *found_entry = find_entry(fd); if (found_entry != NULL && found_entry->is_vfat) return ctx.vfs_vfat->read(ctx.vfs_vfat, fd, buf, count, nodata, error); return ctx.vfs_ext4->read(ctx.vfs_ext4, fd, buf, count, nodata, error); } static ssize_t _write(struct vfs *self, Handle fd, const void *buf, size_t count, int *error) { (void)self; struct entry *found_entry = find_entry(fd); if (found_entry != NULL && found_entry->is_vfat) return ctx.vfs_vfat->write(ctx.vfs_vfat, fd, buf, count, error); return ctx.vfs_ext4->write(ctx.vfs_ext4, fd, buf, count, error); } static int _close(struct vfs *self, Handle fd, int *error) { (void)self; struct entry *found_entry = find_entry(fd); if (found_entry != NULL && found_entry->is_vfat) return ctx.vfs_vfat->close(ctx.vfs_vfat, fd, error); return ctx.vfs_ext4->close(ctx.vfs_ext4, fd, error); } /* Конструктор пользовательского VFS-бэкенда. ctx.vfs_vfat и ctx.vfs_ext4 инициализируются * как стандартные бэкенды с именем "client". */ static struct vfs *_vfs_backend_create(Handle client_id, const char *config, int *error) { (void)config; ctx.vfs_vfat = _vfs_init("client", client_id, "VFS1", error); assert(ctx.vfs_vfat != NULL && "Can't initialize client backend!"); assert(ctx.vfs_vfat->dtor != NULL && "VFS FS backend has not set the destructor!"); ctx.vfs_ext4 = _vfs_init("client", client_id, "VFS2", error); assert(ctx.vfs_ext4 != NULL && "Can't initialize client backend!"); assert(ctx.vfs_ext4->dtor != NULL && "VFS FS backend has not set the destructor!"); return &ctx.wrapper; } /* Регистрация пользовательского VFS-бэкенда под именем custom_client */ static void _vfs_backend(create_vfs_backend_t *ctor, const char **name) { *ctor = &_vfs_backend_create; *name = "custom_client"; } REGISTER_VFS_BACKEND(_vfs_backend)

Компоновка программы Client

Создание статической библиотеки VFS-бэкенда:

CMakeLists.txt

... add_library (backend_client STATIC "src/backend.c") ...

Компоновка программы Client со статической библиотеки VFS-бэкенда:

CMakeLists.txt

... add_dependencies (Client vfs_backend_client backend_client) target_link_libraries (Client pthread ${vfs_CLIENT_LIB} "-Wl,--whole-archive" backend_client "-Wl,--no-whole-archive" backend_client ) ...

Установка параметров запуска и переменных окружения программ

Init-описание примера:

init.yaml

entities: - name: vfs_backend.Client connections: - target: vfs_backend.VfsFirst id: VFS1 - target: vfs_backend.VfsSecond id: VFS2 env: _VFS_FILESYSTEM_BACKEND: custom_client:VFS1,VFS2 - name: vfs_backend.VfsFirst args: - -l - ahci0 /mnt1 fat32 0 env: _VFS_FILESYSTEM_BACKEND: server:VFS1 - name: vfs_backend.VfsSecond - -l - ahci1 /mnt2 ext4 0 env: _VFS_FILESYSTEM_BACKEND: server:VFS2
В начало
[Topic vfs_backends]

Динамическая настройка сетевого стека

Чтобы изменить параметры сетевого стека, заданные по умолчанию, нужно использовать функцию sysctl() или sysctlbyname(), объявленные в заголовочном файле sysroot-*-kos/include/sys/sysctl.h из состава KasperskyOS SDK. Параметры, которые можно изменить, приведены в таблице ниже.

Настраиваемые параметры сетевого стека

Название параметра

Описание параметра

net.inet.ip.ttl

Максимальное время жизни (англ. Time To Live, TTL) отправляемых IP-пакетов. Не влияет на протокол ICMP.

net.inet.ip.mtudisc

Если имеет значение 1, то задействован режим "Path MTU Discovery" (RFC 1191), влияющий на максимальный размер TCP-сегмента (англ. Maximum Segment Size, MSS). В этом режиме значение MSS определяется ограничениями узлов сети. Если режим "Path MTU Discovery" не задействован, то значение MSS не превышает заданного параметром net.inet.tcp.mssdflt.

net.inet.tcp.mssdflt

Значение MSS (в байтах), которое применяется, если только взаимодействующая сторона не сообщила это значение при открытии TCP-соединения, или не задействован режим "Path MTU Discovery" (RFC 1191). Также это значение MSS передается взаимодействующей стороне при открытии TCP-соединения.

net.inet.tcp.minmss

Минимальное значение MSS, в байтах.

net.inet.tcp.mss_ifmtu

Если имеет значение 1, то значение MSS при открытии TCP-соединения рассчитывается, исходя из максимального размера блока передаваемых данных (англ. Maximum Transmission Unit, MTU) задействованного сетевого интерфейса. Если имеет значение 0, то значение MSS при открытии TCP-соединения рассчитывается, исходя из MTU того сетевого интерфейса, который имеет наибольшее значение этого параметра среди всех имеющихся сетевых интерфейсов (кроме loopback-интерфейса).

net.inet.tcp.keepcnt

Число повторных отправок проверочных сообщений (англ. Keep-Alive Probes, KA) без ответа, после выполнения которых TCP-соединение считается закрытым. Если имеет значение 0, то число отправок KA не ограничено.

net.inet.tcp.keepidle

Время неактивности TCP-соединения, по истечении которого начинают отправляться KA. Задается в условных единицах, которые можно перевести в секунды, разделив на значение параметра net.inet.tcp.slowhz.

net.inet.tcp.keepintvl

Время между повторными отправками KA при отсутствии ответа. Задается в условных единицах, которые можно перевести в секунды, разделив на значение параметра net.inet.tcp.slowhz.

net.inet.tcp.recvspace

Размер буфера для принимаемых по протоколу TCP данных, в байтах.

net.inet.tcp.sendspace

Размер буфера для отправляемых по протоколу TCP данных, в байтах.

net.inet.udp.recvspace

Размер буфера для принимаемых по протоколу UDP данных, в байтах.

net.inet.udp.sendspace

Размер буфера для отправляемых по протоколу UDP данных, в байтах.

Пример настройки MSS:

static const int mss_max = 1460; static const int mss_min = 100; static const char* mss_max_opt_name = "net.inet.tcp.mssdflt"; static const char* mss_min_opt_name = "net.inet.tcp.minmss"; int main(void) { ... if ((sysctlbyname(mss_max_opt_name, NULL, NULL, &mss_max, sizeof(mss_max)) != 0) || (sysctlbyname(mss_min_opt_name, NULL, NULL, &mss_min, sizeof(mss_min)) != 0)) { ERROR(START, "Can't set tcp default maximum/minimum MSS value."); return EXIT_FAILURE; } }
В начало
[Topic vfs_net_stack_dyn_conf]