Всем привет! Я продолжаю развивать свою библиотеку для создания распределённых приложений. Она уже легла в основу новой версии rats-search (распределённый торрент-поисковик) и rasync (синхронизация папок, файлов и исходников между устройствами), а также, судя по всему, используется в стороннем клиенте UltraVNC (VNC-клиент).
Библиотека позволяет развернуть собственную P2P-сеть, связать пользователей между собой и выстроить обмен данными через потоки разных типов — бинарные, строковые и другие. Главная особенность — автоматическое обнаружение участников (peer discovery), что особенно актуально в условиях постоянных блокировок и сетевых ограничений.
На данный момент поддерживаются C/C++, Java (Android), Python и Node.js.
Это очередное обновление: ещё больше стабильности в работе различных функций, значительно улучшены протоколы DHT и BitTorrent. Обо всём подробнее — далее.
Последний стабильный релиз на сегодня — 2.1.3. Исходный код и собранные бинарные файлы доступны для:
Windows (64-bit) / Windows (arm)
Linux (64-bit) / Linux (arm)
Android (32-bit / 64-bit)
macOS (64-bit)
Доступ к функционалу библиотеки организован через FFI (Foreign Function Interface).

Поддерживается следующие возможности:
Поиск пиров в сети — автоматическое обнаружение участников через DHT (совместим с BitTorrent Mainline DHT) для глобальной сети и через mDNS для локальной.
Обход NAT без настройки роутера — встроенная поддержка UPnP, NAT-PMP, STUN, Hole punching (координация через модуль PEX). Библиотека сама просит роутер пробросить порт, поэтому пиры за NAT могут принимать входящие соединения без ручной настройки.
Сквозное шифрование — протокол Noise (Curve25519 + ChaCha20-Poly1305) с автоматическим управлением ключами, взаимной аутентификацией и совершенной прямой секретностью.
Передача файлов — потоковая отправка файлов и целых папок с контролем целостности, возможностью паузы/возобновления/отмены и атомарной доставкой.
Масштабируемый обмен сообщениями — протокол GossipSub для публикации/подписки по темам с организацией сообщений и их фильтрацией.
Поддержка многих языков — единый API для C++, C, Node.js (с TypeScript), Java/Android и Python, работающий на Windows, Linux, macOS и Android.
Удобный API для разработчика — событийная модель (
on(),once(),off()), обмен сообщениями в JSON, отслеживание состояния соединений в реальном времени и гибкая система логирования.
Ключевое изменение 2.1.x: появилась поддержка равноправного транспорта поверх UDP наряду с TCP близкого по духу к QUIC. В UDP-транспорте собраны те же гарантии: нумерация пакетов, кумулятивный ACK с 32-битной SACK-битмапой, RTO по RFC 6298 с правилом Карна, fast retransmit и восстановление пропусков по SACK, контроль перегрузки Reno, попакетный flow control.
Оба транспорта равноправны и выбираются автоматически при установке соединения: если в вашей сети заблокирован UDP, будет использован TCP, и наоборот. Это также сделало возможной полноценную реализацию протокола UDP Hole Punching через модуль PEX (протокол DCUtR).
Новый модуль можно использовать следующим образом, сразу большой пример с поддержкой новых возможностей из 2.1.x:
#include <librats/node/node.h> #include <librats/subsystems/dht_discovery.h> #include <librats/subsystems/mdns_discovery.h> #include <librats/subsystems/peer_exchange.h> #include <librats/subsystems/hole_punch.h> #include <librats/subsystems/port_mapping_service.h> #include <librats/subsystems/reconnection.h> #include <librats/subsystems/ping_service.h> #include <librats/subsystems/pubsub.h> NodeConfig config; config.listen_port = port; config.data_dir = data_dir; // оба транспорта (включены по-умолчанию) config.enable_udp = true; config.enable_tcp = true; // какой транспорт предпочитаем? config.preferred_transport = TransportKind::Udp; Node node(config); // — автоматическое обнаружение — // DHT (WAN): ключом обнаружения служит комната, поэтому встречаются только узлы из одной комнаты. DhtDiscovery::Config dc; dc.discovery_key = room; dc.data_dir = data_dir; // храним таблицу маршрутизации рядом с идентификатором node.add_subsystem(std::make_unique<DhtDiscovery>(std::move(dc))); // mDNS (LAN): обнаружение пиров в одной локальной сети без какой-либо настройки. node.add_subsystem(std::make_unique<MdnsDiscovery>()); // PEX: узнав об одном пире, получаем от него список известных ему пиров и подключаемся к ним. node.add_subsystem(std::make_unique<PeerExchange>()); // — прохождение NAT — // UPnP / NAT-PMP: просим роутер пробросить наш порт снаружи. Протоколы мапятся // независимо, поэтому запрашиваются оба — роутер вполне может согласиться на // один и отказать в другом. node.add_subsystem(std::make_unique<PortMappingService>()); // HolePunch HolePunch::Config hp; hp.enable_relay = true; // разрешать использовать ваш пир для пробивок других адресов (DCUtR) node.add_subsystem(std::make_unique<HolePunch>(std::move(hp))); // Reconnection / Ping / PubSub — как раньше. node.add_subsystem(std::make_unique<ReconnectionService>(rc)); node.add_subsystem(std::make_unique<PingService>()); auto* pubsub = node.add_subsystem(std::make_unique<PubSub>());
Собственно, в обновлённом примере, помимо нового модуля HolePunch, можно заметить ещё одно интересное отличие: теперь пути начинаются с librats. Дело в том, что пакет librats официально доступен в репозитории Microsoft пакетного менеджера vcpkg, и сделано это для совместимости с другими пакетам и исключением любых других пересечений.
И да, теперь библиотеку можно установить через vcpkg

Вместе с библиотекой вышла и новая, более стабильная версия rats-search (торрент поисковика) — 2.2.2. Она построена на той же новой версии.
https://github.com/librats/rats-search/releases


Вышел ещё один проект на librats — синхронизатор папок между устройствами rasync (распределённый rsync). Он позволяет автоматически синхронизировать вложенные папки между устройствами, приводя их в согласованное состояние. Условно говоря, ближайший аналог — это Syncthing на Go, но здесь реализация консольная, на C++, и более компактная.
https://github.com/librats/rasync/releases
Работает это так. На одном компьютере вы запускаете:
rasync --key s3cr3t --discover ./documents ./photos ./code
где ключ служит одновременно и ключом синхронизации, и ключом безопасности для шифрования данных. На другом устройстве вы делаете, в целом, то же самое — и получаете на выходе те же папки с документами, фотографиями и кодом. И так продолжаем делать с другими устройствами где вам нужна синхронизация.
можно поиграться с настройками или указать например другой путь для того же каталога
rasync --key s3cr3t --discover ./somefolder --name documents ./photos ./code
В таком варианте документы сохранит в каталог с другим названием. А --discover включает обнаружение через все доступные источники (mDNS/DHT).

Спасибо всем за внимание

