подсистема роутинга utun - это сеть узлов. у каждого узла есть собственные локальные подсети. глобальная задача: создать у каждого узла полную таблицу маршрутизации. Узлы преимущественно создают связь напрямую друг с другом. Но если это не получается отправляют трафик транзитом через доступные узлы. Иногда бывает что через транзитные узлы метрики лучше чем напрямую. Используем приоритетно узлы с лучшей метриков, при нехватке bandwidth используем разные каналы (агрегируем). Динамически обновлем метрики каналов чтобы при отказе быстро переключаться на другие и не фризить обмен из-за отказов. и узлы обмениваются таблицой маршрутов между собой так чтобы у каждого была актуальная таблица подсетей всех узлов. маршрутами меняются клиенты, подключения которых которые взяты из конфига. и сервера принявшие подключения если клиент инициировал обмен маршрутами. инициируется подключение, клиент отправляет свою таблицу. когда сервер принимает таблицу - сервер помечает что по этому маршруту надо обмениваться маршрутами, далее; - добавляет узел в список рассылки обновлений маршрутов - отправляет свою таблицу - добавляет в свою таблицу отсутствующие маршруты - если что-то добавил: - рассылает измененные маршруты по списку рассылки - список рассылки - это linked-list очередей (также на базе ll_queue - каждый элемент = подписчик). один маршрут = одна отправленная кодограмма при подключении узла или изменении таблицы: узел шлёт свою таблицу формат кодограммы: [0x01 - routing module] [subcmd] [data] subcmd: 1 [route] - отправка маршрута 2, без данных - больше данных нет если сервер получил кодограмму маршрута - он помечает флаг в etcp что с узлом надо обмениваться маршрутами (etcp_conn->routing_exchange_active=2) и добавляет в очередь рассылки маршрутов ========================================= механизм инкрементальной синхронизации (реализация - потом, пока мысли) 1. вычисляем хеш каждой записи в роутинг таблице. используем ip+mask+node_uid 2. потом из этих хешей создаем хеш таблицу (старшие n бит номер ячейки). далее вычисляются хеши каждой ячейки. на первом этапе n=16, на втором - n=16*16 на третьем n=16*16*16. отправляем хеши удаленному узлу в формате: [n, 1 байт] ([индекс хеша 2 байта - используется n старших бит][хеш - 8 байт]) удаленный узел считает свои хеши и сравнивает. где не совпало смотрит сколько записей. если записей не много - передает эти записи. если записей много - добавляет 4 бита к хеш таблице и строит субтаблицу для