You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
5.5 KiB
5.5 KiB
TUN Interface (tun_if)
1. Назначение
Модуль создания и управления виртуальным сетевым интерфейсом (TUN) — точкой входа/выхода всего VPN-трафика. Через TUN-интерфейс ОС отправляет IP-пакеты в uTun и получает обработанные пакеты обратно. Реализует кроссплатформенную абстракцию над платформенными механизмами: Linux (/dev/net/tun), FreeBSD (/dev/tun + TUNSIFHEAD), Windows (WinTun API).
Модель данных — две очереди:
- output_queue — пакеты, прочитанные из TUN (ОС → uTun → routing)
- input_queue — пакеты для записи в TUN (routing → uTun → ОС), с callback
tun_input_queue_callback
2. Как пользоваться
// Инициализация из конфига (основной интерфейс VPN)
tun = tun_init(ua, config);
// или для NAT TUN с явными параметрами
nat_tun = tun_init_nat(ua, "tun_nat", "10.0.1.1", 1500, 0);
// Чтение: очередь output_queue наполняется автоматически (через uasync/epoll),
// обработчик читает через queue_set_callback
struct ll_queue* out = tun_get_output_queue(tun);
// Запись: пакет кладётся в input_queue, callback пишет в TUN
tun_write(tun, buf, len); // прямой вызов, не через очередь
// Завершение
tun_close(tun);
Root-права: требуются на всех платформах для создания TUN-устройств и настройки IP.
Тестовый режим (test_mode=1): вместо реального TUN используется socketpair(AF_UNIX, SOCK_DGRAM). Вторая сторона пары доступна через tun_get_test_fd().
Платформенные различия:
- Linux:
open("/dev/net/tun")+ioctl(TUNSETIFF)сIFF_TUN | IFF_NO_PI, неблокирующий режим черезfcntl(O_NONBLOCK) - FreeBSD:
open("/dev/tun")(cloning device), имя присваивается ядром,ioctl(TUNSIFHEAD)для multi-af (4-байтный заголовок AF),ioctl(TUNSIFMODE)для POINTOPOINT - Windows: WinTun API через
wintun.dll, кольцевой буфер 4 MiB, отдельный read-поток (tun_read_thread_proc), пакеты передаются в main thread черезuasync_post → tun_packet_handler
3. API
Структуры
struct tun_if— хендл интерфейса:fd(Linux/BSD файловый дескриптор),platform_handle/adapter_handle(Windows WinTun),ifname,ifindex, очередиinput_queue/output_queue, пулpoolдля ll_entry, счётчики статистики (bytes_read/written,packets_read/written,read_errors,write_errors)struct tun_packet_data— обёртка для передачи пакета из read-потока (Windows) в main thread: указатели наtun_ifиll_entry
Функции
tun_init(ua, config)/tun_init_nat(ua, ifname, ip, mtu, test_mode)— создают TUN-интерфейс: платформенный init, настройка IP/MTU, поднятие интерфейса, создание очередей, регистрация в uasync (Linux/BSD) или запуск read-потока (Windows).tun_init_nat— вариант для отдельного NAT TUN с явными параметрами вместо конфигаtun_close(tun)— остановка read-потока (Windows), удаление из uasync, слив и освобождение обеих очередей, уничтожение пула, платформенная очистка (close(fd)на Linux,SIOCIFDESTROYна FreeBSD,WintunEndSession+WintunCloseAdapterна Windows)tun_write(tun, buf, len)— прямая запись в TUN (в тестовом режиме — в output_queue, иначеtun_platform_write). Пакет имеет префиксный байт, отбрасываемый при записиtun_inject_packet(tun, buf, len)— инжекция пакета в output_queue (для тестов и Windows-нотификаций)tun_read_packet(tun, buf, len)— тестовый helper: чтение одного пакета из input_queuetun_packet_handler(arg)— callback для main thread (Windows): распаковываетtun_packet_data, кладётll_entryв output_queue- Платформенные функции (
tun_linux.c/tun_freebsd.c/tun_windows.c):tun_platform_init()— создание устройства, настройка IP/MTU, поднятие, получениеifindex,O_NONBLOCKtun_platform_cleanup()— закрытие fd/хендловtun_platform_read()— чтение из TUN (FreeBSD:readvс отделением 4-байтного AF-заголовка)tun_platform_write()— запись в TUN (FreeBSD:writevс AF-заголовком; Windows:WintunAllocateSendPacket+WintunSendPacket)tun_platform_get_poll_fd()— fd для uasync (Windows возвращает -1, используется read-поток)