Files
utun2/src/transport_layer/dummynet_doc.md
T

8.0 KiB

Dummynet — UDP Network Emulator

1. Назначение

Эмулятор сетевых условий: задержка (фиксированная + случайная), сериализация с BWlim и потери пакетов. FULL — UDP-прокси между явно заданными endpoints; INLINE — фильтр потерь в send_hook ETCP_LINK. Задержка и BWlim реализованы в FULL.

2. Как пользоваться

Режим FULL (автономный UDP-прокси)

  1. dummynet_create(ua, bind_ip, listen_port) — создаёт контекст, открывает UDP-сокет на listen_port.
  2. dummynet_set_direction(dn, DUMMYNET_FORWARD, ...) и DUMMYNET_BACKWARD — настраивает параметры для каждого направления.
  3. Источник FORWARD — endpoint, заданный как назначение BACKWARD, и наоборот. Порты независимы; listen_port=0 выбирает ОС.
[dest_backward] → [dummynet: loss/queue limit→delay→serializer] → [dest_forward]
[dest_forward]  → [dummynet: loss/queue limit→delay→serializer] → [dest_backward]
  1. dummynet_filter_create(ua) — создаёт фильтр (нет своего сокета).
  2. dummynet_filter_set_loss(df, permille) — настройка потерь. set_delay пока только сохраняет параметры.
  3. dummynet_filter_attach(df, link) — встраивается в link->send_hook, перехватывая все вызовы socket_sendto.
  4. Дополнительно: dummynet_filter_block_addr/unblock_addr — блокировка отправки на конкретные адреса.

Механизмы эмуляции

Механизм Реализация
Delay (fixed + random) При приёме пакета создаётся uasync-таймер (dummynet_delay_callback). После срабатывания пакет кладётся в ll_queue направления
Bandwidth (serializer) Срок передачи увеличивается на время сериализации текущего пакета; дробные миллисекунды сохраняются. Один таймер направления выпускает все уже готовые пакеты, без накопления ошибки округления таймера
Loss (permille) При приёме: rand() % 1000 < loss_permille → дроп. В INLINE-режиме — в хуке отправки
DROP dummynet_set_mode(dn, dir, DUMMYNET_DROP) теряет новые пакеты и удаляет уже ожидающие, включая delay
HOLD Останавливает сериализацию, сохраняя ограниченную очередь. RUN начинает сериализацию головы заново; накопленное выпускается с BWlim

Статистика

recv/sent — число пакетов, recv_bytes/sent_bytes — UDP-байты без IP/UDP заголовков. dropped — переполнение/ошибка ресурсов или отправки, lost — случайные потери и DROP, blocked — только DROP. queue_size/queue_max учитывают все ожидающие пакеты, включая delay/HOLD. Сброс статистики сохраняет текущий размер очереди. Дополнительные отладочные счётчики: delay_timer_set/fire, shaper_timer_set/fire.

Ключевые нюансы

  • Оба направления нужно настроить до начала трафика; источник проверяется по IP и порту.
  • BWlim задаётся в десятичных кбит/с по UDP-байтам; 0 означает unlimited. RTT без очередей — сумма задержек направлений и сериализации.
  • Таймеры uasync имеют миллисекундную точность: несколько готовых пакетов могут выйти вместе; средняя скорость сохраняется.
  • При достижении max_queue_pkts новый пакет отбрасывается. Лимит включает ещё не сработавшие delay-таймеры.
  • Все операции — в потоке ua. Destroy отменяет также delay-таймеры, освобождает их аргументы и пакеты.
  • INLINE-фильтр в режиме блокировки адреса не дропает пакет, а возвращает len (пакет «успешно отправлен», но фактически никуда не ушёл).

3. API

FULL-режим

Функция Назначение
dummynet_create(ua, bind_ip, listen_port) Создать контекст, открыть UDP-сокет, зарегистрировать в uasync
dummynet_destroy(dn) Закрыть сокет, отменить таймеры, очистить очереди, освободить память
dummynet_set_direction(dn, dir, delay_fixed_ms, delay_random_ms, bw_kbps, max_q, loss_permille, dest_ip, dest_port) Настроить параметры направления
dummynet_set_mode(dn, dir, mode) RUN/DROP/HOLD направления, 0 / -1
dummynet_get_stats(dn, dir) Получить статистику направления
dummynet_reset_stats(dn, dir) Сбросить статистику (-1 = все направления)
dummynet_get_socket(dn) Вернуть fd сокета
dummynet_get_listen_port(dn) Вернуть listen_port
dummynet_get_uasync(dn) Вернуть указатель на UASYNC
dummynet_get_queue_size(dn, dir) Вернуть текущий размер очереди направления
dummynet_get_debug_counters(dn, dir, ...) Вернуть отладочные счётчики таймеров

INLINE-режим (dummynet_filter)

Функция Назначение
dummynet_filter_create(ua) Создать фильтр
dummynet_filter_set_loss(df, permille) Установить вероятность потерь
dummynet_filter_set_delay(df, delay_ms, jitter_ms) Установить задержку (NOTE: в текущей реализации delay не применяется в хуке)
dummynet_filter_attach(df, link) Прикрепить хук к ETCP_LINK
dummynet_filter_detach(df) Открепить хук
dummynet_filter_destroy(df) Уничтожить фильтр
dummynet_filter_get_stats(df) Получить статистику
dummynet_filter_block_addr(df, ip, port) Заблокировать адрес (до 4 адресов)
dummynet_filter_unblock_addr(df, ip, port) Разблокировать адрес

Структуры

Структура Назначение
dummynet_stats Счётчики пакетов/байтов, потерь и размера очереди; точные поля — в dummynet.h
dummynet_dir Внутренняя: параметры направления, очередь, таймеры шейпера, отладочные счётчики
dummynet Контекст FULL-режима: ua, сокет, два dummynet_dir, пул пакетов
dummynet_filter Контекст INLINE-режима: ua, loss_permille, delay, link, статистика, список блокировок

Зависимости

u_async.h, ll_queue.h, memory_pool.h, socket_compat.h, etcp_connections.h (для ETCP_LINK), platform_compat.h