|
|
# 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 |
|
|
```bash |
|
|
./autogen.sh # Generate configure script (if needed) |
|
|
./configure # Configure build |
|
|
make # Build everything |
|
|
make install # Install (requires sudo) |
|
|
``` |
|
|
|
|
|
### Partial Builds |
|
|
```bash |
|
|
cd lib && make # Build only the library |
|
|
cd src && make # Build only the main program |
|
|
cd tests && make # Build only tests |
|
|
``` |
|
|
|
|
|
### Clean Build |
|
|
```bash |
|
|
make clean # Clean object files |
|
|
make distclean # Clean everything including configure files |
|
|
``` |
|
|
|
|
|
## 🧪 Test Commands |
|
|
|
|
|
### Run All Tests |
|
|
```bash |
|
|
make check # Run all tests via automake |
|
|
``` |
|
|
|
|
|
### Run Specific Test |
|
|
```bash |
|
|
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 |
|
|
```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 |
|
|
|
|
|
### Include Order |
|
|
```c |
|
|
// 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: |
|
|
```c |
|
|
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) |
|
|
```c |
|
|
// 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 mode |
|
|
- `utun_instance.c/h` - Root instance lifecycle management |
|
|
- `tun_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 management |
|
|
- `etcp_loadbalancer.c/h` - Multi-link load balancing |
|
|
- `pkt_normalizer.c/h` - Packet fragmentation/reassembly |
|
|
- `routing.c/h` - Routing table management |
|
|
|
|
|
**Crypto (src/)** |
|
|
- `secure_channel.c/h` - AES-CCM encryption with ECC key exchange |
|
|
- `crc32.c/h` - CRC32 checksums |
|
|
|
|
|
**Config (src/)** |
|
|
- `config_parser.c/h` - INI-style config file parsing |
|
|
- `config_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 callbacks |
|
|
- `memory_pool.c/h` - Fast object pool allocator |
|
|
- `debug_config.c/h` - Debug logging system |
|
|
- `timeout_heap.c/h` - Min-heap for timer management |
|
|
- `sha256.c/h` - SHA256 hashing |
|
|
|
|
|
**Tests (tests/)** |
|
|
- `test_etcp_*.c` - ETCP protocol tests |
|
|
- `test_crypto.c` - TinyCrypt AES/CCM tests |
|
|
- `test_ecc_encrypt.c` - ECC encryption tests |
|
|
- `test_ll_queue.c` - Queue functionality tests |
|
|
- `bench_*.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 |
|
|
```c |
|
|
// In source files, define debug before including headers |
|
|
#define DEBUG_CATEGORY_YOUR_MODULE 1 |
|
|
``` |
|
|
|
|
|
### Common Build Issues |
|
|
1. **Missing headers:** Check include paths in Makefile.am |
|
|
2. **Undefined references:** Ensure source files are listed in Makefile.am |
|
|
3. **Link errors:** Check function declarations match definitions |
|
|
|
|
|
### Testing Crypto |
|
|
```bash |
|
|
cd tests/ |
|
|
./test_etcp_crypto # Should show all tests passing |
|
|
cd tests/ |
|
|
./working_crypto_test # Standalone crypto test |
|
|
``` |
|
|
|
|
|
## 📦 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 |
|
|
|
|
|
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. |
|
|
|
|
|
"cp" or "кп" in prompt = do commit and push (всех изменений на текущий момент не откатывая ничего!) |
|
|
|
|
|
Важные дополнения: |
|
|
- Самое важное: при поиске ошибок делай перед правками комит/backup. Всё лишнее что менял при отладке - строго вернуть назад в состояние до моего вмешательства. В итоге в код должно попасть только проверенное исправление и ничего лилшнего! |
|
|
- если в процессе исправлений-доработок возникла нестыковка которая требует сеньезных доработок, остановить и подробно расскажи об этом. |
|
|
- sed для редактирования исходников - запрещено пользоваться! |
|
|
- Проверяй на дублирование кода - не сделано ли это уже в другом месте. |
|
|
- Не делай функций-посредников: лучше сразу вызывать target функцию без вложенных вызовов. |
|
|
- Старайся чтобы функция сделала логически завершенную операцию полностью - это упрощает код и понимание. |
|
|
- нельзя ничего восстанавливать из репозитория не прашивая |
|
|
- Когда пишешь код всегда загружай в контекст и мысленно разберись как работают все функции/струтуры, назначение переменных которые используешь. |
|
|
- Для отладки не printf а DEBUG_* |
|
|
- перед сборкой всегда make clean |
|
|
- прежде чем вносить правки хорошо разберись как должно работать, просмотри все нужные функции полностью, нужно целостное понимание. |
|
|
- при написании кода мысленно анализируй логику работы, думай как сделать проще и удобнее. Проверяй дубликаты и что уже есть, продумай логику до тех пор пока не будет полного понимания |
|
|
|
|
|
Действия при поиске бага: |
|
|
1. создать комит или бэкап всего что меняешь |
|
|
2. когда причина бага найдена и устранена - верни всё остальное что менял в исходное состояние |
|
|
3. проверь что тесты проходят и всё работает. make clean перед сбркой обязательно. |
|
|
4. если баг не устранён - продолжай поиск или если время заканчивается - верни всё в исходное состояние |
|
|
|
|
|
Как более точно эффективно проводить диагностику ошибки: |
|
|
0. Сосредоточься на поиске конкретной ошибки и доведи его до конца руководствуясь этой инструкцией. |
|
|
1. прочитай полностью код функций с ошибкой и код всех функции которые учавствуют в ошибочном алгоритме. |
|
|
2. еще раз мысленно выполни предполагаемый сценарий ошибки (если чего-то не хватает до полной картины - обязательно дочитывай все ветви функций по ходу: нельзя додумывать - нужна точность) и убедись что: |
|
|
- ты точно понимаешь как алгоритм прихдит к ошибке |
|
|
- все функции которые учавствуют в сценарии ошибки проанализированы и их поведение проверено и понятно |
|
|
- последовательно отсекай логически законченные блоки которые проверены и точно правильно работают |
|
|
- если ты полностью проанализировал функцию и к ней нет описания или описание неточное (неполное), и функция работает логически корректно - поправь описание. Если функция работает логически неверно - добавь запись об этом в todo.txt |
|
|
3. Если исправление как либо меняет поведение функции: |
|
|
- просмотри где используется эта функция |
|
|
- убедись что изменение поведения не повлияет на остальные места где функция используется. особенно важный пункт для библиотек и модулей коммуникаций |
|
|
|
|
|
Работа с очередями. |
|
|
- Запись в очередь: очереди забивать нельзя. Добавляй следующий элемент только когда очередь стала пустой. Пользуйся наблюдателем 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 |
|
|
|
|
|
Для удобства навигции по C коду есть скрипт в корне проекта: ./c_util (пока глючит!) |
|
|
|
|
|
Команды: |
|
|
./c_util toc - Выводит кратко список всех файлов проекта, прототипов функций/структур/enum по всем файлам. |
|
|
./c_util describe <имя_функции/структуры/enum> <имя2> ... - выводит прототипы запрошенных элементов с комментариями |
|
|
./c_util show <имя_функции/структуры/enum> <имя2> ... - выводит полный код элементов (включая комментарии перед ними) |
|
|
./c_util edit lib/debug_config.c 135 70 38 7D <<'EOF' |
|
|
void debug_set_level(debug_level_t new_level) { |
|
|
g_debug_config.level = new_level; |
|
|
} |
|
|
EOF - редактирование с проверкой контрольных сумм. начиная со строки 135, далее ксуммы заменяемых строк ( в примере 3 строки - 70 38 7D). вместо них вписать текст << (может быть другоч число строк) |
|
|
|
|
|
Если функция/структура не найдена, скрипт выведет сообщение об ошибке. Скрипт игнорирует комментарии и препроцессорные директивы при парсинге, но захватывает их для вывода. |
|
|
|
|
|
|
|
|
|
|
|
*Last updated: 2025-01-20 - After full crypto implementation and testing* |