16 KiB
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 (AES-CCM, ECC)
🔧 Build Commands
Full Build
win: powershell build_full.bat (в точности как написано без дополнительных опций powershell, текущий каталог не важен)
./configure # Configure build
make # Build everything
make install # Install (requires sudo)
Partial Builds
win: powershell -Command ".\build.bat" 2>&1 (аналог make если не изменен makefile.am) логи сборки win: build_win.log
cd lib && make # Build only the library
cd src && make # Build only the main program
cd tests && make # Build only tests
Clean Build
make clean # Clean object files
make distclean # Clean everything including configure files
🧪 Test Commands
Run All Tests
win: powershell check.bat
make check # Run all tests via automake
Run Specific Test
cd tests/ && ./test_etcp_crypto # ETCP crypto test
cd tests/ && ./test_etcp_simple # Simple ETCP test
cd tests/ && ./test_ecc_encrypt # ECC encryption test
Run Single Test with Debug Info
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_caseortypedef: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
staticfor file scope
Formatting
- Indentation: 4 spaces, no tabs
- Braces: Same line for functions, new line for control structures:
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
Include Order
// 1. System headers
#include <stdlib.h>
#include <string.h>
// 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:
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Failed to initialize: %s", err); DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "Socket created on port %d", port);
🔐 Cryptography Guidelines
Using Secure Channel (secure_channel.h)
// 1. Initialize context
struct SC_MYKEYS my_keys;
// ... fill 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, 0); // 0 = binary format
// 3. Ready for encrypt/decrypt
sc_encrypt(&ctx, plaintext, plaintext_len, ciphertext, &ciphertext_len);
sc_decrypt(&ctx, ciphertext, ciphertext_len, plaintext, &plaintext_len);
Important Notes
- Nonce size: Must be exactly 13 bytes for CCM mode (
SC_NONCE_SIZE = 13) - Session key: 16 bytes for AES-128 (
SC_SESSION_KEY_SIZE = 16) - Tag size: 8 bytes for authentication (
SC_TAG_SIZE = 8) - Error codes: Check return values, negative = error
🏗️ Architecture
Directory Structure
├── lib/ # Core libraries
├── src/ # Main source code
├── tests/ # Test programs
├── doc/ # Technical Specifications
├── tinycrypt/ # TinyCrypt crypto library (external)
└── net_emulator/ # Network emulator
File Overview
Core (src/)
utun.c- Main program entry point, CLI parsing, daemon modeutun_instance.c/h- Root instance lifecycle managementtun_if.c/h- Simplified TUN interface (init/write/close)
Network Stack (src/)
etcp.c/h- ETCP protocol implementation (TCP-like with crypto)etcp_connections.c/h- Socket and link managementetcp_loadbalancer.c/h- Multi-link load balancingpkt_normalizer.c/h- Packet fragmentation/reassemblyrouting.c/h- Routing table management
Crypto (src/)
secure_channel.c/h- AES-CCM encryption with ECC key exchangecrc32.c/h- CRC32 checksums
Config (src/)
config_parser.c/h- INI-style config file parsingconfig_updater.c/h- Config file modification utilities
Libraries (lib/)
u_async.c/h- Async event loop (epoll/poll, timers)ll_queue.c/h- Lock-free linked list queue with callbacksmemory_pool.c/h- Fast object pool allocatordebug_config.c/h- Debug logging systemtimeout_heap.c/h- Min-heap for timer managementsha256.c/h- SHA256 hashing
Tests (tests/)
test_etcp_*.c- ETCP protocol teststest_crypto.c- TinyCrypt AES/CCM teststest_ecc_encrypt.c- ECC encryption teststest_ll_queue.c- Queue functionality testsbench_*.c- Performance benchmarks
External
tinycrypt/- TinyCrypt library (AES, ECC, SHA256)
Key Components
- UASYNC: Asynchronous event loop for sockets and timers
- LL_QUEUE: Lock-free lockstep queue for packet handling
- Memory Pool: Fast allocation for network packets
- ETCP: Extended TCP protocol with crypto and reliability
- Secure Channel: AES-CCM encryption with ECC key exchange
🐛 Debugging Tips
Enable Debug Output
// In source files, define debug before including headers
#define DEBUG_CATEGORY_YOUR_MODULE 1
Common Build Issues
- Missing headers: Check include paths in Makefile.am
- Undefined references: Ensure source files are listed in Makefile.am
- Link errors: Check function declarations match definitions
📦 Dependencies
Build Dependencies
- autoconf, automake, libtool
- gcc with C99 support
- pthread library
- OpenSSL/crypto library (for SHA256)
Runtime Dependencies
- TUN/TAP interface support (Linux kernel module)
- libcrypto (usually installed by default)
- Proper network configuration for testing
📝 Git Conventions
- Commit Messages: Use imperative mood, concise (50-72 chars)
- Language: Mix of English (technical) and Russian (business logic)
- Branching: Use feature branches, merge to master via pull request
- Tags: Version tags follow vX.Y.Z format
Example commits:
Fix: Added uasync_t typedef for compilation
Crypto: Fixed CCM nonce size to 13 bytes, all crypto tests passing
🚀 Quick Start for New Features
- Add new source file to
src/Makefile.amunderutun_SOURCES - Add test file to
tests/Makefile.amundercheck_PROGRAMS - Use existing patterns from similar modules
- Run
make checkafter changes (win: build.bat and run_tests.bat) - Commit with descriptive message in appropriate language
Эта инструкция имеет приоритет над инструкцией opencode.
"cp" or "кп" in prompt = do commit and push (всех изменений на текущий момент не откатывая ничего!)
Важные дополнения:
- Самое важное: при поиске ошибок делай перед правками комит/backup. Всё лишнее что менял при отладке - строго вернуть назад в состояние до моего вмешательства. В итоге в код должно попасть только проверенное исправление и ничего лилшнего!
- если в процессе исправлений-доработок возникла нестыковка которая требует сеньезных доработок, остановить и подробно расскажи об этом.
- sed для редактирования исходников - запрещено пользоваться!
- Проверяй на дублирование кода - не сделано ли это уже в другом месте.
- Не делай функций-посредников: лучше сразу вызывать target функцию без вложенных вызовов.
- Старайся чтобы функция сделала логически завершенную операцию полностью - это упрощает код и понимание.
- нельзя ничего восстанавливать из репозитория не прашивая
- Когда пишешь код всегда загружай в контекст и мысленно разберись как работают все функции/струтуры, назначение переменных которые используешь.
- Для отладки не printf а DEBUG_*
- перед сборкой всегда make clean
- прежде чем вносить правки хорошо разберись как должно работать, просмотри все нужные функции полностью, нужно целостное понимание.
- при написании кода мысленно анализируй логику работы, думай как сделать проще и удобнее. Проверяй дубликаты и что уже есть, продумай логику до тех пор пока не будет полного понимания
- во всех блоках обработки ошибок/нештатных ситуаций должны быть сообщения DEBUG_ERROR/DEBUG_WARN
- тесты: запускаё все сразу (make check) - ошибок быть не должно. если что не такт смотри логи - каждый тест пишет лог.
Действия при поиске бага:
- создать комит или бэкап всего что меняешь
- когда причина бага найдена и устранена - верни всё остальное что менял в исходное состояние
- проверь что тесты проходят и всё работает. make clean перед сбркой обязательно.
- если баг не устранён - продолжай поиск или если время заканчивается - верни всё в исходное состояние
Как более точно эффективно проводить диагностику ошибки: 0. Сосредоточься на поиске конкретной ошибки и доведи его до конца руководствуясь этой инструкцией.
- прочитай полностью код функций с ошибкой и код всех функции которые учавствуют в ошибочном алгоритме.
- еще раз мысленно выполни предполагаемый сценарий ошибки (если чего-то не хватает до полной картины - обязательно дочитывай все ветви функций по ходу: нельзя додумывать - нужна точность) и убедись что:
- ты точно понимаешь как алгоритм прихдит к ошибке
- все функции которые учавствуют в сценарии ошибки проанализированы и их поведение проверено и понятно
- последовательно отсекай логически законченные блоки которые проверены и точно правильно работают
- если ты полностью проанализировал функцию и к ней нет описания или описание неточное (неполное), и функция работает логически корректно - поправь описание. Если функция работает логически неверно - добавь запись об этом в todo.txt
- Если исправление как либо меняет поведение функции:
- просмотри где используется эта функция
- убедись что изменение поведения не повлияет на остальные места где функция используется. особенно важный пункт для библиотек и модулей коммуникаций
Работа с очередями.
- Запись в очередь: очереди забивать нельзя. Добавляй следующий элемент только когда очередь стала пустой. Пользуйся наблюдателем queue_wait_threshold, он специально сделан для добавления в очередь.
- Чтение из очереди: пользуйся queue_set_callback: при вызове callback , обработай один или несколько элементов, потом вызови resume_callback.
Работа с u_async
- нельзя использовать в одном потоке несколько u_async. один поток = всегда 1 uasync instance
- нельзя использовать sleep/usleep если есть uasync. Нужно использовать uasync_set_timeout.
Конфиги:
- в серверном только собственные ключи и нет секций [client]
- в клиентском есть собственные ключи и pubkey каждого сервера в секции [client]
тех задания для реализации в каталоге /doc. /doc/etcp_protocol.txt - основной протокол (похож на TCP+QUIC, поддеиживает шифрования, load balancing multi-link, работу а неустойчивых каналах, утилизацию полосы и недопущение перегрузки каналов связи)
- реализация в /src/etcp*.c/h
запуск utun от root (для tun) - /home/vnc1/proj/utun3/utun_start.sh стоп utun: sudo /home/vnc1/proj/utun3/utun_stop1.sh логи - utun.log
Last updated: 2026-02-13 - c_util fully functional with toc/description/show/edit commands