Align route table and observation documentation
This commit is contained in:
1 parent
1ad8ff73ad
commit
30a69712fc
3 files changed
+43
-39
No files matched your search
@@ -1,31 +1,34 @@
|
||||
В таблице роутинга маршруты не пересекаются. Т.е. не может быть одновременно 192.168.1.1/24 и 192.168.1.100/30
|
||||
|
||||
Как работает роутинг:
|
||||
1. типов маршрута бывает два: learned (роутятся в ETCP instance) и local (роутятся в TUN).
|
||||
local - локальные маршруты из конфига (опция конфига my_subnet=IP/Mask)
|
||||
при инициализации local сразу добавляются в роутинг таблицу (ипользуя запись BGP_NODEINFO_PACKET* my_nodeinfo).
|
||||
|
||||
BGP_NODEINFO собирается на узле владельце node, далее распространяется по остальным узлам.
|
||||
|
||||
2. При установке подключения к новому узлу мы отправляем этому узлу все nodeinfo. Если несколько доступных линков - отправляем только один - preferred_conn
|
||||
3. При изменении preferred_conn рассылаем reroute (например старый preferred_conn удален)
|
||||
3. При удалении всех подключений рассылаем withdraw.
|
||||
|
||||
3. При получении BGP_NODEINFO_PACKET мы смотрим есть ли такой узел уже в таблице. Если узла нет - добавляем, если есть - обновляем информацию о узле включая его маршруты и список next_hop через которые доступен узел (nb_routes).
|
||||
Добавляем так:
|
||||
инкрементируем hop_count
|
||||
устанавливая etcp линк с которого приняли как next_hop, добавляем его в hop_list.
|
||||
рассылаем по всем активным линкам кроме линка с которого получили (обязательно)
|
||||
Обновление: обновляем hop_list если поменялся
|
||||
|
||||
4. При отключении от узла (если у node не осталось nb_routes) мы:
|
||||
Удаляем node и вложенные структуры: все маршруты узла
|
||||
Рассылаем withdraw для узла hop_id.
|
||||
|
||||
Логика рассылки withdraw:
|
||||
Если получен withdraw - удаляем этот маршрут и распространяем withdraw или reroute по всем линкам кроме того с которого получили. В зависимости от изменений (остались ли резервные линки или изменился preferred_conn).
|
||||
|
||||
Метрик маршрута пока нет. используется первый доступный.
|
||||
|
||||
Как работаеут маршрутизация:
|
||||
destination IP -> route table lookup -> route entry (ip/mask, node_info*) -> выбор лучшего next_hop -> отправка в next_hop
|
||||
route_lib — локальная таблица IPv4-подсетей UTUN
|
||||
================================================
|
||||
|
||||
Подсети в таблице не пересекаются. Запрещены одинаковые и вложенные диапазоны,
|
||||
как между узлами, так и внутри одного переданного набора. Например,
|
||||
10.0.0.0/8 исключает 10.1.0.0/24; соседние 10.1.0.0/24 и 10.1.1.0/24 допустимы.
|
||||
Маршрут /0 занимает всё адресное пространство и может быть только единственным.
|
||||
|
||||
route_insert(table, node) добавляет все node->subnets->v4_subnets атомарно.
|
||||
Префиксы должны быть в диапазоне 0..32; адреса нормализуются маской перед хранением.
|
||||
При неверных аргументах, отсутствии подсетей, пересечении или OOM возвращает false,
|
||||
не меняя таблицу и её статистику. Перед заменой маршрутов узла вызывают route_delete.
|
||||
|
||||
Таблица — отсортированный массив. route_lookup получает IPv4 в host byte order
|
||||
и бинарным поиском возвращает единственный подходящий диапазон либо NULL.
|
||||
Это не LPM-таблица: вложенные префиксы исключены при вставке.
|
||||
Указатель на ROUTE_ENTRY действителен только до следующего изменения таблицы.
|
||||
Адреса TOPO_SUBNET4 хранятся в сетевых байтах, parse_subnet возвращает host order,
|
||||
is_local_subnet принимает network order. parse_subnet сохраняет host-биты и читает
|
||||
префикс через atoi; это не строгий валидатор всей строки CIDR.
|
||||
|
||||
TOPO_GROUP_NODE заимствован, в том числе для локальных маршрутов.
|
||||
Маршруты удаляют до освобождения узла. destroy освобождает массив, но не узлы.
|
||||
Все вызовы выполняются в одном потоке ядра.
|
||||
|
||||
Наполнение таблицы и поиск следующего узла — разные задачи:
|
||||
IPv4 destination -> route_lookup -> TOPO_GROUP_NODE -> etcp_route_send
|
||||
-> выбор живого next hop через CM/BGP -> ETCP.
|
||||
Для локального владельца routing доставляет пакет в TUN после firewall.
|
||||
Групповые пути, WITHDRAW, выбор по числу переходов и READY описаны в topo_group.h;
|
||||
общая подписанная запись узла — в topo_node.h и doc/node_snapshot.md.
|
||||
|
||||
IPv6-таблица route6_lib использует radix и разрешает вложенные префиксы.
|
||||
Основной routing.c пока доставляет только IPv4.
|
||||
@@ -25,7 +25,7 @@ int route_ping_addr_equal(const struct sockaddr_storage *a, const struct sockadd
|
||||
|
||||
/* Отправить OBSERVE PING: group/round и generation сокета ненулевые, timeout_ms — мс.
|
||||
* peer_key — 32 байта ключа наблюдателя, peer_address — его UDP endpoint.
|
||||
* Возвращает результат etcp_send_ping_to_socket (0/-1), callback/arg — его контракт.
|
||||
* Возвращает 0 при запуске, отрицательный код ошибки ETCP при отказе; callback/arg — контракт ETCP.
|
||||
* Ответ: address(19) || tag(33); профиль сокета здесь не изменяется. */
|
||||
int route_ping_observe(struct ETCP_SOCKET *socket, const uint8_t peer_key[SC_PUBKEY_SIZE],
|
||||
const struct sockaddr_storage *peer_address, uint64_t group, uint64_t round, int timeout_ms,
|
||||
|
||||
@@ -4,15 +4,16 @@
|
||||
`ETCP_SOCKET`. Выбор B/C, пересылка управляющих сообщений и классификация
|
||||
профиля принадлежат `nat_detection`; алгоритм — в `doc/nat_detection.txt`.
|
||||
|
||||
`route_ping_observe(socket, peer_key, peer_address, round, timeout_ms, callback, arg)`
|
||||
`route_ping_observe(socket, peer_key, peer_address, group, round, timeout_ms, callback, arg)`
|
||||
передаёт PING с `ETCP_PING_FLAG_OBSERVE`. PONG содержит фактически наблюдаемый
|
||||
source IP:port и исходный тег. Профиль не меняется от единственного ответа.
|
||||
`route_ping_observation` проверяет размер, ID/поколение сокета и round.
|
||||
`route_ping_observation` проверяет размер, ID/поколение сокета, round и group.
|
||||
|
||||
Адрес занимает 19 байт: family(1: 4/6), IP(16: IPv4 + 12 нулей либо IPv6),
|
||||
port(2, BE). Тег занимает 25 байт: `NAT2UDP!`(8), socket_id(1),
|
||||
generation(8, BE), round(8, BE). Неправильные family, скрытые IPv4-байты
|
||||
и нулевой порт отвергаются. Новый wire не использует native packed integers.
|
||||
port(2, BE). Тег занимает 33 байта: `NAT4UDP!`(8), socket_id(1),
|
||||
generation(8, BE), round(8, BE), group(8, BE). Декодирование отвергает неправильные
|
||||
family, скрытые IPv4-байты и нулевой порт. IPv6 scope_id в wire не передаётся.
|
||||
Кодирование нулевой порт не запрещает. Числа тега передаются в BE.
|
||||
|
||||
В транспорте nonce генерируется CSPRNG; PONG должен соответствовать ожидаемому
|
||||
ключу, source IP:port и принимающему socket generation. Pending снимается
|
||||
@@ -20,8 +21,8 @@ generation(8, BE), round(8, BE). Неправильные family, скрытые
|
||||
совпадающие запросы без callback; arg остаётся собственностью вызывающего.
|
||||
|
||||
`ETCP_PING_FLAG_ADDRESS_CHECK` обозначает прямое входящее испытание. Его
|
||||
receipt фиксируется на рабочем сокете владельца до отправки PONG. Потеря
|
||||
обратного PONG поэтому не превращает полученный ingress в отрицательный результат.
|
||||
приём передаётся `nat_detection_receive_ingress` без UDP-ответа: ответ мог бы
|
||||
испортить историю контактов. Результат передаётся по защищённому управляющему каналу.
|
||||
UDP-результаты не используются для TCP listener и SOCKS5 endpoint.
|
||||
|
||||
Проверки: `tests/test_route_ping.c`, `tests/test_nat_detection.c`,
|
||||
|
||||
Reference in new issue
Block a user