14 KiB
AGENTS.md - uTun Development Guide
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
./autogen.sh # Generate configure script (if needed)
./configure # Configure build
make # Build everything
make install # Install (requires sudo)
Partial Builds
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
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