- u_async.c: process immediate_queue BEFORE epoll_wait in uasync_poll - stcp_link.c: defensive NULL etcp_conn/etcp_link in stcp_link_close - utun_instance.c: move stcp_server_list_destroy_all to Phase J (before ETCP), add deferred drain in both Phase J and L - stcp.h/c: STCP_HS_ENC_CLIENT 6→38, STCP_HS_ENC_SERVER 7→39, exchange ed25519_pubkey in both handshake directions - etcp_connections.c: copy peer_ed25519 from STCP to ETCP_CONN in etcp_link_enter_ready_tcp; guard link->etcp in tcp_link_close_cb - chat_sync.c: fix lk->conn NULL dereference for TCP links - test_stcp.c: update stcp_server_create/stcp_client_connect callsites - tools/chat_tcp_test: change transport udp→tcp
86 lines
7.7 KiB
Markdown
86 lines
7.7 KiB
Markdown
Архитектура etcp:
|
||
|
||
ETCP устанавливает только одно подключение между двумя узлами. Это подключение может добавлять-убирать каналы связи (динамически) без разрыва соединения.
|
||
Также каналы связи мониторятся и трафик распределяется между доступными каналами. Если канал определяется как недоступен - он исключается из обмена.
|
||
Все каналы периодически мониторятся на доступность (keepalive).
|
||
|
||
Роутинг.
|
||
utun поддерживает встроенный ipv4 роутинг, может через промежуточные узлы доставлять пакеты.
|
||
У каждого узла есть свои маршруты. Эти маршруты при подключении распространяются по остальным узлам.
|
||
Связь между узлами:
|
||
Каждый узел имеет настройку NAT для каждого listen сокета: public / nat / private.
|
||
public - нет nat, можно подключаться напрямую
|
||
nat - есть правильный nat с static port (т.е. можно подключаться напрямую зная присвоенный ip:port)
|
||
private - нельзя подключаться
|
||
Приоритетный способ обмена данными - прямое подключение к узлу. Если один из узлов имеет не private интерфейс то создается подключение через него.
|
||
Если не удается подключиться напрямую - выбирается переадча через промежуточный узел с наилучшим качеством канала (считается из задержки, числа хопов, bandwidth, потерь)
|
||
Для установки прямого соединения шлётся запрос удаленному узлу через существующие соединения на запрос подключения.
|
||
Запрос включает мой id, pubkey, доступные каналы связи и их [ip:port]. удаленный узел запоминает эти данные и отправляет response с такими же данными.
|
||
При получении request или response узел смотрит каких подключений (links) еще нет и пробует инициировать на подходщих линках с узлом.
|
||
Таким образом будет инициировано подключение между узлами по всем доступным линкам.
|
||
Если у каждого из узлов есть более одного канала то создаётся m * n подключений (каждый сокет с каждым). которые дальше работают как обычно - балансировщик нагрузки далее в процессе выбирает как лучше отправить очередной пакет (больше вариантов - можно найти путь лучше).
|
||
Есть статические подключения (которые прописаны в конфиге) и есть динамические - которые устанавливаются в процессе по необходимости.
|
||
Обмен маршрутами происходит только через статические подключения.
|
||
|
||
|
||
## etcp_connections:
|
||
- обслуживает encrypt/decrypt и установку защищенного подключения per-link.
|
||
- для одного etcp соединения может испольоваться несколько подключений одновременно (load balancing / filover)
|
||
|
||
## etcp_loadbalancer:
|
||
- выбирает через какой маршрут отправить пакет
|
||
- ограничивает rate отправки чтобы не забивать очереди каналов
|
||
- сделан для совместной работы с etcp модулем
|
||
|
||
## pkt_normalizer:
|
||
- обеспечивает фрагментацию и сборку пакетов в единый поток для передачи через etcp.
|
||
- взаимодейстует с etcp и очередями для приема и передачи.
|
||
- в очередь для передачи может отправить любой модуль
|
||
- из очереди приёма пакеты забирает etcp_api
|
||
|
||
## etcp_api:
|
||
- обеспечивает связь между etcp и остальными модулями
|
||
- имеет функцию которая забирает из normalizer принятые данные и перенаправляет их на нужный модуль
|
||
- имеет функцию connector_bind которой можно установить коллбэк для нужного типа кодограмм (первый байт).
|
||
|
||
## etcp:
|
||
- обеспечивает ретрансмиссии при передаче и сборку в правильной последовательности при приёме
|
||
- взаимодействует с pkt_normalizer и с udp сокетами для отправки-получения пакетов
|
||
|
||
## stcp_* :
|
||
- аналогично etcp только упрощенный вариант, используя tcp в качестве транспорта.
|
||
|
||
## etcp_router:
|
||
- устанавливает связь между узлами, маршрутизирует трафик через цепочку узлов
|
||
|
||
## route_lib, route6_lib :
|
||
- управляет таблицами маршрутизации (ipv4/ipv6 lookup)
|
||
|
||
## route_node:
|
||
- хранит список доступных узлов (полученные от соседей) и их адреса/pubkeys для подключения.
|
||
- содержит апи для поиска-чтения-обновления узла
|
||
|
||
## route_bgp:
|
||
- составляет карту маршрутизации между узлами и обновляет ее при подключении-отключении узлов
|
||
|
||
## route_ping:
|
||
- модуль для определения типа nat (strict или eim) используя вспомогательный узел
|
||
|
||
Библиотеки:
|
||
## uasync
|
||
- модуль для асинхронной работы.
|
||
реализует сокеты, таймауты и сигналы из других потоков
|
||
- быстро работает с большим числом таймаутов (timeout_heap)
|
||
|
||
## ll_queue
|
||
- модуль работы с очередями, использует uasync.
|
||
- реализует fifo/lifo очереди, быстрый поиск по индексу, различные callback - сигнализация о состояниях очереди,
|
||
- congestion control: если много желающих записать -> очередь round-robin
|
||
|
||
|
||
Тесты:
|
||
# Правила работы с очередями в тестах:
|
||
- для добавления в очередь надо использовать queue_waiter_wait и queue_set_threshold, добавлять по одному пакету, каждый раз дожидаясь когда очередь станет пустой.
|
||
- для получения надо использовать queue_set_callback + queue_resume_callback
|
||
|