Describe checked datagram startup and bounded TCP HUP handling
This commit is contained in:
1 parent
e2ee5f2397
commit
f10a6f70c5
2 files changed
+41
-14
No files matched your search
+34
-14
@@ -68,6 +68,11 @@ Backpressure router и окно потока независимы. При оши
|
||||
Force обходит лимит send_q router, но никогда не окно proxy.
|
||||
При отсутствии CONNECTED/кредита (-2) отправка ждёт ready/WINDOW, а не только router waiter.
|
||||
|
||||
OS TCP сохраняет ограничение read_high_water и явную остановку чтения при HUP.
|
||||
Если HUP не оставляет работы для чтения/записи, tcp_io временно снимает регистрацию fd;
|
||||
low_water восстанавливает её с новой generation. Сокет и очереди сохраняются, запись
|
||||
обслуживается независимо от чтения. Ошибка повторной регистрации закрывает соединение.
|
||||
|
||||
## Half-close и удаление потока
|
||||
|
||||
Владелец выставляет fin_pending только после отправки всех исходящих DATA.
|
||||
@@ -87,6 +92,7 @@ FIN не должен ждать записи противоположного
|
||||
Клиентский close_pending может повторяться в poll/free пока поток жив; сервер после
|
||||
ошибки TCP удаляет поток и делает попытку ERROR. Гарантированного повторения CLOSE/ERROR
|
||||
после освобождения владельца нет.
|
||||
Поздний WINDOW отсутствующего потока отбрасывается с debug-диагностикой, без создания потока.
|
||||
|
||||
Router close/restart уведомляет сервис entry длиной 26 байт без payload.
|
||||
Proxy называет это CLOSE_ALL: exit удаляет потоки указанного peer, клиент — все свои
|
||||
@@ -133,13 +139,22 @@ UDP exit создаёт сокет на tuple client_node_id/src_ip/src_port/dst
|
||||
проверяет источник ответа, меняет src/dst местами в REPLY. Удаляет неактивные flows
|
||||
при очередной периодической проверке с порогом >60 с. Клиент восстанавливает IPv4 checksum,
|
||||
UDP checksum=0 (допустимо для IPv4).
|
||||
Flow публикуется только после socket/nonblocking/bind/read registration и создания
|
||||
таймера очистки. Ошибка продления общего таймера закрывает оставшиеся flows.
|
||||
sendto проверяется по точной длине, включая успешный нулевой payload; EINTR повторяется.
|
||||
EAGAIN/ENOBUFS и ошибки отдельного пакета логируются без очереди повторов; сломанный
|
||||
сокет удаляется. Ошибки выделения ответа, router send и доставки в TUN диагностируются.
|
||||
|
||||
ICMP exit использует один raw socket; заменяет id/seq token и сопоставляет
|
||||
wire_id/wire_seq/IP цели с pending. Исходные id/seq восстанавливаются для клиента.
|
||||
Порог ожидания >5 с проверяется периодически. Raw reply проходит проверку ICMP checksum.
|
||||
Нечётный хвост checksum обрабатывается без чтения за буфером.
|
||||
test_loopback даёт виртуальный ответ только при отсутствии raw socket.
|
||||
Успешный ICMP init не гарантирует raw socket: его ошибка оставляет контекст активным.
|
||||
`icmp_proxy_init` создаёт общий контекст и binding; `icmp_proxy_enable_exit` отдельно
|
||||
открывает raw socket. EPERM/EACCES/отсутствие поддержки raw отключают только ICMP exit
|
||||
с WARN; клиентские REPLY сохраняются. Прочие ошибки запуска прерывают создание instance.
|
||||
Тестовый `test_loopback` включается явно, закрывает raw socket и даёт виртуальные ответы
|
||||
независимо от прав процесса. Production его не включает.
|
||||
Pending raw request создаётся только с рабочим таймером истечения срока ожидания.
|
||||
|
||||
Send API принимает payload 0..65507, TUN delivery — 0..65506 из-за однобайтового
|
||||
префикса в uint16_t длине entry. UDP send требует локальный UDP-контекст, ICMP send
|
||||
@@ -148,11 +163,13 @@ Send API принимает payload 0..65507, TUN delivery — 0..65506 из-з
|
||||
## Жизненный цикл, диагностика и проверки
|
||||
|
||||
Все операции и callbacks — в uasync владельца. Proxy init запрашивает binding
|
||||
после router init; client/server имеют разные service IDs. Сервер создаёт UDP/ICMP,
|
||||
клиент делает это при наличии TUN. Сначала уничтожается клиент, затем сервер:
|
||||
клиент сохраняет общие UDP/ICMP пока сервер включён, server destroy уничтожает их.
|
||||
После удаления exit-потоков ua должен обработать отложенные free.
|
||||
Ошибки listener/bind/подмодулей не всегда пробрасываются init/create — точные контракты в .h.
|
||||
после router init; client/server имеют разные service IDs. Общие UDP/ICMP создаёт
|
||||
и уничтожает UTUN_INSTANCE; TCP-модули освобождают только собственные ресурсы.
|
||||
Контексты нужны для включённого exit либо клиентского TUN; SOCKS/HTTP без TUN их не требуют.
|
||||
Заданные listeners, TUN mappings и bindings обязательны: ошибка откатывает создание.
|
||||
Повторный init активного модуля и попытка занять чужой binding отклоняются.
|
||||
При уничтожении instance TCP-клиент/сервер и общие контексты закрываются до остановки
|
||||
групп и транспорта; ua обрабатывает отложенные free. Точные контракты — в .h.
|
||||
|
||||
Категория proxy: info — подключения/закрытия/транзакции, debug — окна/паузы/повторы,
|
||||
trace — трафик и секундная диагностика exit TCP-очередей/пулов/OS buffers.
|
||||
@@ -164,17 +181,20 @@ trace — трафик и секундная диагностика exit TCP-о
|
||||
| test_http_proxy | HTTP codec, разбиения headers/chunks, framing, лимиты, source credit, Upgrade |
|
||||
| test_proxy_packets | IPv4/UDP/ICMP, checksum и payload длиной 0..1501 |
|
||||
| test_proxy_regressions | Handshake/CONNECTED, HTTP pipeline/EOF/deadlines, окна/FIN, peer+sid, reentrancy, TUN options/fragment validation, per-instance UDP/ICMP |
|
||||
| test_proxy_lifecycle | 25 сценариев отказов/rollback, fd/память/таймеры, владение bindings, ICMP без raw, HUP re-register и destroy из callback |
|
||||
| test_tcp_proxy_client | Create/destroy с тестовым TUN, без утечек |
|
||||
| test_tcp_proxy_server | TCP echo через tcp_conn; сам по себе не проверяет протокол exit |
|
||||
| test_socks_http_proxy | Реальные SOCKS IPv4/domain, HTTP и HTTPS CONNECT, byte-exact загрузки |
|
||||
| test_udp_proxy / test_icmp_proxy | Два instance через ETCP; ICMP использует raw socket либо тестовый fallback |
|
||||
| test_socks_http_proxy | Реальные SOCKS IPv4/domain, HTTP и HTTPS CONNECT, byte-exact загрузки; штатный TLS shutdown либо UTUN_TEST_TLS_ABRUPT=1 |
|
||||
| test_udp_proxy / test_icmp_proxy | Два instance через ETCP; ICMP выбирает явный test_loopback при недоступном raw socket |
|
||||
| test_tcp_io | 19 сценариев, включая HUP high/low-water на epoll/poll, ручную паузу и независимую запись |
|
||||
| test_tcp_io_flush | Callback после последнего синхронного send |
|
||||
|
||||
Аудит 2026-10-24: перечисленные девять тестовых программ пересобраны и прошли на Linux.
|
||||
ICMP прошёл через test_loopback: raw socket недоступен без соответствующих прав.
|
||||
В успешном SOCKS/HTTP-тесте остались EPIPE/ENOTCONN при teardown, а тестовые конфиги
|
||||
логируют неподдержанный enabled в секции сервера; наблюдения записаны в [tasks.md](tasks.md).
|
||||
Полный check.sh, реальные TUN/load/burst и Windows/FreeBSD в этом аудите не запускались.
|
||||
Проверка 2026-10-24: профильные тесты проходят на Linux. ICMP без прав на raw проверен
|
||||
через явный test_loopback. Штатный TLS shutdown проходит без EPIPE/ENOTCONN;
|
||||
аварийный сохраняет реальные ошибки записи, все 16 загрузок остаются byte-exact.
|
||||
Тестовые конфиги используют поддержанный connect_timeout. Итоги полного прогона
|
||||
и sanitizer-проверок — в [proxy_fix_plan.txt](proxy_fix_plan.txt).
|
||||
Windows/FreeBSD runtime и настоящий raw ICMP в этом окружении не проверены.
|
||||
Создание proxy из конфигурации в utun_instance.c исключено под _WIN32.
|
||||
IPv4-фрагменты на входе proxy TUN отклоняются; сборки фрагментов нет.
|
||||
Описания модулей: `src/proxy/*_doc.md`; все семь заголовков `src/proxy/*.h` сверены с реализацией.
|
||||
Reference in new issue
Block a user