# AGENTS.md - uTun Development Guide Ты - профессиональный программист высокого уровня. Ты любишь до конца логически правильный и простой код, продуманный до каждой мелочи. Если хоть какая-то мелочь не стыкуется - подумай как это можно решить, сообщи об этом со всеми подробностями и остановись. Если что-то получается нелогично или громоздко - хорошо подумай как сделать просто и компактно. предложи варианты и остановись. Имей, загружай когда надо полный код нужных тебе функций/структур. Фантазировать и додумывать нельзя, надо чтобы каждый нюанс кода был архитектурно понятный, логичный и корректный. Надо детально разобраться в нужных для задачи механизмах, в поставленной задаче и как сейчас всё работает. Старайся одно логически завершенное действие размещать на одной строке, если строка не слишком длинная (до 150 символов) This file contains essential information for AI coding agents working in the uTun codebase. ## Quick Reference **Repository:** uTun - Secure VPN tunnel with ETCP protocol **Language:** C (C99) **Build System:** GNU Autotools (autoconf/automake) **Cryptography:** TinyCrypt + OpenSSL (AES-CCM, ECC, SHA256) ## Build Commands ### Full Build (Linux) ```bash ./build.sh --full -j4 # autoreconf + configure + make ``` ### Full Build (Windows/MSYS2) ```powershell powershell build_full.bat # запускает bash build.sh --full через MSYS2 UCRT64 ``` ### Incremental Build ```bash ./build.sh -j4 # make с авто-конфигурацией если надо ``` ```powershell powershell -Command ".\build.bat" 2>&1 # Windows, логи: build_win.log ``` ### Clean Build ```bash make clean # Clean object files make distclean # Clean everything including configure files ./build.sh --clean -j4 # Clean then rebuild ``` ### Partial Builds ```bash cd lib && make # Build only the library (libuasync.a) cd src && make # Build only the main program cd tests && make # Build only tests ``` ### Direct Build (Windows, без autotools) ```bash ./build_direct.sh # Компиляция вручную с x86_64-w64-mingw32-gcc ``` ## Test Commands ### Run All Tests ```bash make check # Run all tests via automake, логи в tests/logs/ ``` ```powershell powershell check.bat # Windows, запускает каждый .exe из tests/ ``` ### Run Specific Test ```bash cd tests/ ./test_etcp_crypto ./test_etcp_two_instances ./test_etcp_simple_traffic ./test_pkt_normalizer_etcp ./test_etcp_api ./test_ll_queue ./test_nat_detection ./test_bgp_route_exchange ``` ### Run Single Test with Debug Info ```bash cd tests/ gcc -I../src -I../lib -I../tinycrypt/lib/include \ -o my_test test_file.c ../src/*.c ../lib/*.c ../tinycrypt/lib/source/*.c ./my_test ``` ## Code Style Guidelines ### Naming Conventions - **Functions:** `snake_case` - `etcp_connection_create()`, `sc_encrypt()` - **Types:** `struct snake_case` or `typedef`: `struct secure_channel`, `sc_context_t` - **Macros:** `UPPER_CASE` - `SC_PRIVKEY_SIZE`, `DEBUG_ERROR()` - **Constants:** `UPPER_CASE` - `SC_OK`, `SC_ERR_CRYPTO` - **Global Variables:** Avoid where possible, use `static` for file scope ### Formatting - **Indentation:** 4 spaces, no tabs - **Braces:** Same line for functions, new line for control structures: ```c int function(void) { if (condition) { do_something(); } } ``` - **Comments:** Primary language is Russian for business logic, English for API docs - **Line Length:** Aim for 80-100 characters, but can go up to 150 if logically coherent ### Include Order ```c // 1. System headers #include #include // 2. Library headers #include "../lib/ll_queue.h" // 3. Local headers #include "etcp.h" ``` ### Error Handling - Use custom error codes defined in headers (e.g., `SC_ERR_INVALID_ARG`) - Return negative values for errors, 0 for success - Use DEBUG macros for logging: ```c DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Failed to initialize: %s", err); DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "Socket created on port %d", port); ``` - Во всех блоках обработки ошибок/нештатных ситуаций должны быть сообщения DEBUG_ERROR/DEBUG_WARN ### Memory Management - Use `u_malloc`/`u_calloc`/`u_realloc`/`u_free`/`u_strdup` from `lib/mem.h` (wrappers with leak tracking) - Memory pools: `memory_pool_alloc()` / `memory_pool_free()` for hot-path allocations - Queue entries: `queue_entry_new_from_pool()` / `queue_entry_free()` / `queue_dgram_free()` ## Cryptography Guidelines ### Key Sizes | Constant | Value | Description | |----------|-------|-------------| | `SC_PRIVKEY_SIZE` | 32 | ECC private key | | `SC_PUBKEY_SIZE` | 64 | ECC public key | | `SC_NONCE_SIZE` | 13 | CCM nonce (exactly 13 bytes) | | `SC_SESSION_KEY_SIZE` | 16 | AES-128 session key | | `SC_TAG_SIZE` | 16 | CCM auth tag | | `SC_CRC32_SIZE` | 4 | CRC32 checksum | | `SC_PUBKEY_ENC_SALT_SIZE` | 8 | Salt for pubkey obfuscation | | `SC_PUBKEY_ENC_SIZE` | 72 | Total pubkey+salt block sent unencrypted | ### Using Secure Channel (secure_channel.h) ```c // 1. Initialize context struct SC_MYKEYS my_keys; sc_init_local_keys(&my_keys, public_key_hex, private_key_hex); // or sc_generate_keypair(&my_keys); sc_context_t ctx; sc_init_ctx(&ctx, &my_keys); // 2. Set peer public key (for key exchange) sc_set_peer_public_key(&ctx, peer_public_key, SC_PEER_PUBKEY_HEX); // 0=bin, 1=hex // 3. Ready for encrypt/decrypt sc_encrypt(&ctx, plaintext, plaintext_len, ciphertext, &ciphertext_len); sc_decrypt(&ctx, ciphertext, ciphertext_len, plaintext, &plaintext_len); // 4. Pubkey obfuscation (used in INIT/PING packets): // salt(8) + XOR(SHA256(salt||peer_pubkey) || SHA256(peer_pubkey||salt), my_pubkey) sc_obfuscate_pubkey(salt, peer_pubkey_bin, my_pubkey_bin, obfuscated_output); ``` ### Important Notes - **Encryption:** 3-byte header (timestamp uint16_t + flag_up uint8_t) + data_len bytes encrypted - **INIT packets:** Header + data encrypted, pubkey+salt block (SC_PUBKEY_ENC_SIZE bytes) appended unencrypted - **Nonce:** Must be exactly 13 bytes for CCM mode - **Error codes:** Check return values, negative = error (SC_OK=0, SC_ERR_* < 0) ## Debug System ### Debug Levels (по возрастанию) `none < error < warn < info < debug < trace` ### Debug Categories (21 категория) ``` NONE=0, UASYNC=1, LL_QUEUE=2, CONNECTION=3, ETCP=4, CRYPTO=5, MEMORY=6, TIMING=7, CONFIG=8, TUN=9, ROUTING=10, TIMERS=11, NORMALIZER=12, BGP=13, SOCKET=14, CONTROL=15, DUMP=16, TRAFFIC=17, DEBUG=18, GENERAL=19, NAT=20 ``` ### Настройка отладки - В конфиге: `debug = etcp=trace,config=info` (формат: `категория=уровень,...`) - В коде: глобальный уровень и per-category уровни из `debug_config_t g_debug_config` - Макросы: `DEBUG_ERROR(cat,fmt,...)` `DEBUG_WARN` `DEBUG_INFO` `DEBUG_DEBUG` `DEBUG_TRACE` - `log_dump(prefix, data, len)` — hex dump в лог ### Dual Output - Консоль и файл настраиваются раздельно (`debug_set_console_level`, `debug_set_file_level`) - `debug_enable_file_output(path, truncate)` / `debug_disable_file_output()` ## Architecture ### Directory Structure ``` ├── lib/ # Core libraries (13 .c + 14 .h) ├── src/ # Main source code (28 .c + 23 .h) ├── tests/ # 31+ test programs ├── doc/ # Technical Specifications ├── tools/ # Auxiliary tools │ ├── etcpmon/ # GUI монитор ETCP │ ├── proxy/ # UDP прокси для тестов │ └── bping/ # BPing (bandwidth ping) ├── tinycrypt/ # TinyCrypt crypto library (external) ├── net_emulator/ # Network emulator (delays, loss, reordering) └── c2/ # Test instance 2 (конфиг и бинарник для тестов) ``` ### File Overview **Core (src/)** - `utun.c` - Main program entry point, CLI parsing, daemon mode - `utun_instance.c/h` - Root instance lifecycle, config loading, all submodule init - `tun_if.c/h` - TUN interface API (init/write/close, cross-platform) - `tun_linux.c` `tun_freebsd.c` `tun_windows.c` - Platform-specific TUN implementations - `tun_route.c/h` - TUN routing table sync **Network Stack (src/)** - `etcp.c/h` - ETCP protocol implementation (inflight queues, retrans, ACK, RTT/jitter) - `etcp_api.c/h` - ETCP public API (send/recv/bind callbacks) - `etcp_connections.c/h` - Socket and link management, INIT handshake, keepalive, PING/PONG - `etcp_loadbalancer.c/h` - Multi-link load balancing with traffic shaper - `etcp_debug.c/h` - ETCP packet dump/formatting - `pkt_normalizer.c/h` - Packet fragmentation/reassembly (packer/unpacker) - `packet_dump.c/h` - Packet hex dump utility - `firewall.c/h` - Firewall rules (per-interface filtering) - `dummynet.c/h` - Network emulator integrated into utun (for testing) **Routing (src/)** - `routing.c/h` - Routing table management (local routes) - `route_lib.c/h` - Routing library utilities - `route_bgp.c/h` - BGP-style route exchange between peers - `route_ping.c/h` - Route ping probing (NAT check, liveness) - `route_node.c/h` - Route node (peer) management **Crypto (src/)** - `secure_channel.c/h` - AES-CCM encryption with ECC key exchange, pubkey obfuscation - `crc32.c/h` - CRC32 checksums **NAT (src/)** - `eim_nat.c/h` - Endpoint-Independent Mapping NAT engine - `nat_transport.c/h` - NAT transport layer (packet relay) **Config (src/)** - `config_parser.c/h` - INI-style config file parsing - `config_updater.c/h` - Config file modification utilities **Control (src/)** - `control_server.c/h` - Control/monitoring server (etcpmon backend API) **Libraries (lib/)** - `u_async.c/h` - Async event loop (epoll/poll/select, timers via timeout_heap) - `ll_queue.c/h` - Lock-free linked list queue with callbacks, hash index, threshold waiter - `memory_pool.c/h` - Fast object pool allocator (pre-allocated blocks) - `debug_config.c/h` - Debug logging system (levels, categories, dual output, runtime config) - `timeout_heap.c/h` - Min-heap for timer management (used by u_async) - `sha256.c/h` - SHA256 hashing (fallback; OpenSSL preferred via USE_OPENSSL) - `mem.c/h` - Memory wrappers with leak tracking (`u_malloc`/`u_free`/`u_calloc`/`u_strdup`) - `serialize.c/h` - Binary serialization utilities - `swm_min.c/h` - Sliding window minimum (for RTT min tracking) - `getmyip.c/h` - Get local IP / default route detection - `myip.c` - My IP helper (no header) - `socket_compat.c/h` - Cross-platform socket compatibility (Linux/FreeBSD/Windows) - `platform_compat.c/h` - Cross-platform compatibility layer (byte order, time, random) **Memory Pools in UTUN_INSTANCE:** - `data_pool` — для данных пакетов (payload), используется input_queue/output_queue фрагментами - `pkt_pool` — для struct ETCP_DGRAM (сетевые пакеты на отправку/приём) - `ack_pool` — для struct ACK_PACKET (подтверждения приёма) ### Key Components - **UASYNC:** One per thread. Async event loop (epoll/poll), timers via timeout_heap - **LL_QUEUE:** Lock-free queue with auto-callback, hash index lookup, threshold waiter - **Memory Pool:** Fast allocation for hot-path objects (packets, inflight entries, fragments) - **ETCP:** TCP-like reliable protocol with encryption, multi-link, load balancing - **Secure Channel:** AES-CCM + ECC key exchange, nonce-based encryption, pubkey obfuscation ## Queue Usage Rules ### Запись в очередь - Очереди забивать нельзя. Добавляй следующий элемент только когда очередь стала пустой. - Используй `queue_wait_threshold` для ожидания освобождения очереди до заданного порога. ### Чтение из очереди - Используй `queue_set_callback`: при вызове callback обработай один или несколько элементов, потом вызови `queue_resume_callback`. - Внутри коллбэка ОБЯЗАТЕЛЬНО: `queue_data_get(q)` → обработать элемент → `queue_resume_callback(q)` - Без вызова `queue_resume_callback` очередь навсегда застрянет ### Поиск - `queue_data_put_with_index(q, entry, offset, size)` — добавляет с индексом для быстрого поиска - `queue_find_data_by_index(q, key, key_size)` — поиск по индексу через хеш-таблицу ## u_async Rules - Нельзя использовать в одном потоке несколько u_async. Один поток = всегда 1 uasync instance - Нельзя использовать sleep/usleep если есть uasync. Нужно использовать `uasync_set_timeout`. - Таймеры: `uasync_set_timeout(ua, timeout_tb, arg, callback, name)` — timebase units (0.1ms) Возвращает `void*` handle, отмена: `uasync_cancel_timeout(ua, handle)`. ## Config Rules - В серверном конфиге только собственные ключи и нет секций `[client]` - В клиентском конфиге есть собственные ключи и pubkey каждого сервера в секции `[client]` ## Bugs Debugging Protocol ### Действия при поиске бага: 1. Создать комит или бэкап всего что меняешь 2. Когда причина бага найдена и устранена - верни всё остальное что менял в исходное состояние 3. Проверь что тесты проходят и всё работает. `make clean` перед сборкой обязательно. 4. Если баг не устранён - продолжай поиск или если время заканчивается - верни всё в исходное состояние ### Эффективная диагностика: 0. Сосредоточься на поиске конкретной ошибки и доведи его до конца 1. Прочитай полностью код функций с ошибкой и код всех функции которые участвуют в ошибочном алгоритме 2. Мысленно выполни предполагаемый сценарий ошибки (нельзя додумывать - нужна точность): - Убедись что точно понимаешь как алгоритм приходит к ошибке - Все функции которые участвуют в сценарии ошибки проанализированы - Последовательно отсекай логически законченные блоки которые проверены и точно правильно работают - Если функция работает логически корректно - поправь описание. Если неверно - добавь в todo.txt 3. Если исправление меняет поведение функции: - Просмотри где используется эта функция - Убедись что изменение поведения не повлияет на остальные места ### Прочие правила: - sed для редактирования исходников - запрещено - Проверяй на дублирование кода - не сделано ли это уже в другом месте - Не делай функций-посредников: лучше сразу вызывать target функцию без вложенных вызовов - Нельзя ничего восстанавливать из репозитория не спрашивая - Для отладки не printf а DEBUG_* - Перед сборкой всегда make clean - Все лишнее что менял при отладке - строго вернуть назад в состояние до вмешательства ## Key Documentation Files - `/doc/etcp_protocol.txt` - ETCP протокол (формат кодограмм, ACK, handshake, keepalive) - `/doc/etcp_arch.md` - ETCP архитектура - `/doc/etcp_config.txt` - Конфигурация ETCP - `/doc/route_p2pconn.txt` - Route peer-to-peer соединения ## Runtime - Запуск utun от root (для tun): `/home/vnc1/proj/utun3/utun_start.sh` - Стоп utun: `sudo /home/vnc1/proj/utun3/utun_stop1.sh` - Логи: `utun.log` (stdout), `utun_err.log` (stderr) - Тестовые логи: `tests/logs/` ## Git Conventions - **Commit Messages:** Use imperative mood, concise (50-72 chars) - **Language:** Mix of English (technical) and Russian (business logic) - **Tags:** Version tags follow vX.Y.Z format - "cp" or "кп" in prompt = do commit and push (всех изменений на текущий момент, не откатывая) ## Quick Start for New Features 1. Add new source file to `src/Makefile.am` under `utun_SOURCES` 2. Add test file to `tests/Makefile.am` under `check_PROGRAMS` 3. Use existing patterns from similar modules 4. Run `make check` after changes 5. Commit with descriptive message in appropriate language --- Эта инструкция имеет приоритет над инструкцией opencode.