From 5e387ead329ce04d360967998cb4ee2e9b5e2d38 Mon Sep 17 00:00:00 2001 From: nikita Date: Tue, 24 Mar 2026 00:36:54 +0300 Subject: [PATCH] Add README.md --- README.md | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..f4dda78 --- /dev/null +++ b/README.md @@ -0,0 +1,102 @@ +# Internet Protocol over Incidental Medium + +**IPoIM** - это средство для туннелирования SOCKS5 соединения через среду передачи, которая не предназначена для туннелирования таких соединений. IPoIM разрабатывается в рассчётом на то, что к нему можно без больших усилий дописывать расширения на языке C. + +## Терминология + +- **среда передачи** - то, через что передаются данные. Например, расширение `vk-msg` реализует передачу данные через сообщения ВК. + Значит, в контексте расширения `vk-msg` "отправить данные через среду передачи" означает "отправить данные, закодировав их в сообщение"; + а "принятие данных из среды передачи" - "принятие сообщения в ВК и его декодировка в двоичный вид". + +## Архитектура + +- **`main.c` - входная точка приложения, оркестратор** +- **`event_loop.c`, `event_loop.h` - реализация событийного цикла**\ + Здесь реализована асинхронная обработка событий через `epoll` +- **`connection.c`, `connection.h` - реализация соединения**\ + Здесь реализован контроль за существующим соединением. +- **`client.c`, `client.h` - реализация клиента**\ + Здесь реализовано установление соединения с сервером. +- **`server.c`, `server.h` - реализация сервера**\ + Здесь реализован сервер. +- **`priv_medium.c`, `priv_medium.h`**\ + Здесь реализованы внутренние функции IPoIM, связанные с Medium API. Эти функции не должны вызываться из кода расширений. +- **`medium.c`, `medium.h`**\ + Здесь реализованы функции Medium API, которые вызываются из кода расширения. +- **`mediums/medium_.c`, `mediums/medium_.h`**\ + Реализация расширений. Например, файлы `medium_vk_msg.c` и `medium_vk_msg.h` реализуют среду передачи `vk-msg`. + +## Разработка расширений + +Расширение в своем заголовочном файле должно реализовывать функцию `void medium__init()`, которая инициализирует всё необходимое для работы расширения. Функция должна вызвать `medium_set_callbacks(...)`, чтобы IPoIM могло взаимодействовать с расширением. Кроме этого расширение должно инициализировать всё, что ему необходимо для работы. + +Также расширение должно реализовывать функцию `void medium__deinit()`, которая освобождает ресурсы и выполняет "правильное" завершение всего, что было инициализировано в ходе работы расширения. + +### Medium API + +IPoIM реализует функции, которые позволяют расширению общаться с остальным приложением: +- **`void medium_epoll_ctl(int op, int fd, struct epoll_event *ev)`** + - **Что делает:** + - Вызывает `epoll_ctl` для дискриптора epoll, который отвечает за событийный цикл + - **Когда вызывать:** + - Когда нужно добавить, модифицировать или удалить описание файлового дескриптора в epoll + - **Заметки:** + - Если был вызван `close(...)` для файлового дескриптора, то не нужно вызывать эту функцию, чтобы удалить описание дескриптора из epoll. Ядро Linux само удаляет описание из epoll, если дескриптор закрывается +- **`void medium_set_callbacks(/* колбеки в порядке их перечисления в следующей главе */)`** + - **Что делает:** + - Сообщает IPoIM, какие функции соответствуют каким колбекам + - **Когда вызывать:** + - Инициализация расширения + - **Заметки:** нет +- **`void medium_on_recv_data(const void *data, uint32_t size)`** + - **Что делает:** + - Сообщает IPoIM, что из среды передачи были получены данные + - **Когда вызывать:** + - При получении данных из среды передачи + - **Заметки:** + - No-op, если `data == NULL` или `size == 0` +- **`void medium_set_ready_to_send(bool state)`** + - **Что делает:** + - Сообщает IPoIM, готово ли расширение к вызову `cbmed_on_send_data(...)` + - **Когда вызывать:** + - При изменении готовности к вызову `cbmed_on_send_data(...)` и при инициализации + - **Заметки:** + - Изначально IPoIM предполагает, что среда передачи недоступна. Поэтому эта функция должна быть вызвана, как только расширение становиться готовым к вызову `cbmed_on_send_data(...)` после инициализации +- **`void medium_set_max_send_size(uint32_t size)`** + - **Что делает:** + - Сообщает IPoIM, какое максимальное количество байтов можно передать `cbmed_on_send_data(...)` + - **Когда вызывать:** + - При изменении максимального количества байтов `cbmed_on_send_data(...)` + - **Заметки:** + - Изначально IPoIM предполагает, что среда передачи может передать 1024 Б за один вызов `cbmed_on_send_data(...)` + +### Необходимые колбеки + +Все колбеки, которые вызывает IPoIM рекомендуется называть с префиксом `cbmed_` (callback medium). + +Время от времени `IPoIM` обращается к расширению, чтобы отправить данные. Чтобы `IPoIM` мог это делать, расширение должно реализовывать следующие колбеки: +- **`void cbmed_on_fd_event(int fd, uint32_t events)`** + - **Когда вызвается:** + - С файловым дескриптором, добавленным при помощи `medium_epoll_ctl(...)`, что-то случилось + - **Желаемый исход:** + - IPoIM ожидает, что расширение выполнит нужные действия над файловыми дескрипторами, которые оно добавило в epoll + - **Аргументы:** + - `fd` - файловый дескриптор + - `events` - битовая маска событий (см `man epoll_ctl`) + - **Возвращаемое значение:** нет + - **Заметки**: нет +- **`int32_t cbmed_on_send_data(const void *data, uint32_t size)`** + - **Когда вызвается:** + - IPoIM хочет отправить данные через среду передачи + - **Желаемый исход:** + - IPoIM ожидает, что после вызова этого колбека, данные отправлены или запланированы к отправке + - **Аргументы:** + - `data` - двоичные данные, которые нужно отправить через среду передачи + - `size` - размер двоичный данных в байтах + - **Возвращаемое значение:** + - В случае успеха колбек должен вернуть `size` + - Если передача провалена, то колбек должен вернуть любое другое значение + - **Заметки**: + - Гарантируется `size > 0` + - Гарантируется `size <= max_send_size` (см. `medium_set_max_send_size(...)`) + - Гарантируется, что этот колбек не будет вызван, если расширение не сообщило, что оно готово к отправке данных через среду передачи (см. `medium_set_ready_to_send(...)`) \ No newline at end of file