Документация
Всё о том, как MTRTracer собирается, что показывает, откуда берёт каждую цифру и как читать результат. Поиск слева ищет по всему тексту.
Обзор
MTRTracer непрерывно отправляет ICMP-пакеты к цели с растущим TTL (числом хопов, которые пакет может пройти). Каждый роутер на пути, у которого TTL истёк, отвечает сообщением «время жизни истекло», и так становятся известны все узлы маршрута. Пакеты уходят раундами, статистика по каждому хопу копится и обновляется в реальном времени, как в WinMTR и mtr.
Поверх этого программа:
- даёт выбрать, через какой сетевой адаптер отправлять пакеты, и объясняет, как устроены VPN-туннели;
- определяет имя, сеть (AS) и место каждого узла по нескольким источникам и проверяет место по скорости света;
- рисует маршрут на карте и анимирует пакеты;
- пишет каждый пакет в лог с точностью до микросекунд, фиксирует события и разбирает результат словами;
- сохраняет историю и сравнивает запуски;
- показывает, какие программы держат сетевые соединения.
Есть версии для Windows (окно на WebView2) и Linux (окно на WebKitGTK или браузер). Интерфейс и логика одинаковые.
Требования
| Что | Windows | Linux |
|---|---|---|
| Система | Windows 10 1809+ или 11, x64 | x64 или arm64, glibc (Ubuntu 22.04+, Debian 12+, Fedora 38+, Arch и т.п.) |
| Окно интерфейса | Microsoft Edge WebView2 Runtime (в Windows 11 уже есть) | libwebkit2gtk-4.1, libgtk-3, libnotify; без них работает режим --browser |
| Права | обычный пользователь | обычный пользователь, если разрешены ping-сокеты (см. Linux) |
| Для сборки | .NET 10 SDK, Node.js 20+ | .NET 10 SDK, Node.js 20+, bash, tar |
| Размер | около 80 МБ (самодостаточный exe) | около 80 МБ (самодостаточный файл) |
Готовая программа не требует установленного .NET: всё нужное упаковано в один файл. Visual Studio для сборки не нужна.
Готовые сборки
Собранные файлы лежат в GitHub Releases. Их собирает GitHub Actions из исходников репозитория по тегу версии, рядом лежит SHA256SUMS.txt.
| Файл | Для чего |
|---|---|
MTRTracer-windows-x64.exe | Windows 10/11 x64, один файл, запускается без установки |
mtrtracer-linux-x64.tar.gz | Linux x64: программа, иконка, ярлык и install.sh |
mtrtracer-linux-arm64.tar.gz | Linux ARM64 (Raspberry Pi 4/5, ARM-серверы) |
Проверка целостности на Linux: sha256sum -c SHA256SUMS.txt --ignore-missing; на Windows: Get-FileHash MTRTracer-windows-x64.exe и сравнить со строкой в файле.
Exe не подписан сертификатом, поэтому Windows SmartScreen при первом запуске может предупредить: «Подробнее» → «Выполнить в любом случае». Если не хотите доверять готовому файлу, соберите программу сами, как описано ниже.
Сборка на Windows
Один раз поставьте инструменты:
winget install Microsoft.DotNet.SDK.10 winget install OpenJS.NodeJS.LTS
Затем в корне проекта:
powershell -ExecutionPolicy Bypass -File .\build.ps1
Скрипт по порядку:
- устанавливает зависимости интерфейса (
npm ci) и собирает его вui\dist; - прогоняет юнит-тесты (они не выходят в сеть);
- публикует
dist\MTRTracer.exe: один самодостаточный файл со встроенным интерфейсом.
| Параметр | Что делает |
|---|---|
-FrameworkDependent | маленький exe без встроенного .NET; на компьютере нужен .NET 10 Desktop Runtime |
-SkipTests | пропустить тесты |
-Linux | дополнительно собрать Linux-версию (кросс-сборка) в dist-linux\mtrtracer-linux-x64.tar.gz |
-LinuxArch arm64 | Linux-версия для ARM64 вместо x64 |
То же вручную:
cd ui; npm ci; npm run build; cd .. dotnet test src\MTRTracer.Tests -c Release dotnet publish src\MTRTracer.App -c Release -r win-x64 -o dist --self-contained true -p:PublishSingleFile=true -p:IncludeNativeLibrariesForSelfExtract=true -p:EnableCompressionInSingleFile=true
Интерфейс встраивается в exe на шаге публикации, поэтому npm run build обязан идти раньше. Если забыть, программа при запуске покажет сообщение об этом вместо пустого окна.
Сборка и установка на Linux
Зависимости
| Дистрибутив | Команда |
|---|---|
| Ubuntu, Debian | sudo apt install dotnet-sdk-10.0 nodejs npm libwebkit2gtk-4.1-0 libnotify4 |
| Fedora | sudo dnf install dotnet-sdk-10.0 nodejs npm webkit2gtk4.1 libnotify |
| Arch | sudo pacman -S dotnet-sdk nodejs npm webkit2gtk-4.1 libnotify |
Если .NET 10 нет в репозиториях вашего дистрибутива, поставьте его скриптом Microsoft dotnet-install.sh или из пакетов Microsoft. WebKitGTK нужен только для окна; собирать можно и без него.
Сборка
./build.sh # linux-x64 ./build.sh --arch arm64 # linux-arm64 ./build.sh --skip-tests # без тестов
Результат: dist-linux/mtrtracer-linux-x64.tar.gz. Внутри файл MTRTracer, иконка, ярлык .desktop и install.sh.
Установка
tar -xzf mtrtracer-linux-x64.tar.gz cd linux-x64 ./install.sh
Установщик работает без root и кладёт файлы в домашнюю папку:
- программа:
~/.local/opt/mtrtracer/MTRTracer, командаmtrtracerв~/.local/bin; - ярлык в меню приложений и иконка;
- проверка WebKitGTK и прав на ICMP с подсказками, что выполнить.
| Команда | Что делает |
|---|---|
./install.sh | установить или обновить |
./install.sh --setcap | то же и выдать программе cap_net_raw через sudo, если ping-сокеты запрещены |
./install.sh --remove | удалить программу (данные в ~/.local/share/MTRTracer остаются) |
Разработка
Интерфейс можно смотреть в обычном браузере на демо-данных, без сети и без C#-части:
cd ui && npm run dev # http://localhost:5173
В этом режиме работает встроенный симулятор (ui/src/bridge/mock.ts): адаптеры и туннель, трассировка с потерями и балансировкой, неверные кандидаты геолокации, anycast-цель, VPN-режим, история. Специальные цели: blocked.example (цель без ICMP, включается TCP-пинг) и nonexistent.invalid (ошибка DNS).
Настоящее приложение с горячей перезагрузкой интерфейса на Windows:
# терминал 1 cd ui; npm run dev # терминал 2 $env:MTRTRACER_DEV_URL = "http://localhost:5173"; dotnet run --project src\MTRTracer.App
В dev-режиме в окне работают F12 и Ctrl+R. В обычной сборке инструменты разработчика включаются переменной MTRTRACER_DEVTOOLS=1. На Linux инспектор включает флаг --devtools.
Первый запуск и выбор адаптера
При каждом запуске открывается окно выбора сетевого адаптера. Пакеты трассировки уйдут с адреса выбранного интерфейса, поэтому от выбора зависит, какой маршрут вы увидите.
| Вариант | Что происходит |
|---|---|
| Авто | пакеты идут так, как решит таблица маршрутизации системы; рядом подписано, через какой адаптер сейчас идёт маршрут по умолчанию |
| Конкретный адаптер | пакеты привязываются к его адресу и выходят через него, даже если маршрут по умолчанию другой (например, Ethernet в обход VPN) |
| VPN-адаптер + VPN-режим | хопы до сервера VPN через физический адаптер и сквозная задержка до цели через туннель (см. VPN-режим) |
Для каждого адаптера показаны тип (Ethernet, Wi-Fi, VPN/туннель, виртуальный, мобильный), адреса IPv4 и IPv6, шлюз, DNS-серверы, MAC, скорость, MTU, способ получения адреса и живой трафик. Отметки:
- Маршрут по умолчанию: через этот адаптер сейчас идёт трафик в интернет;
- Нет выхода в интернет: у адаптера нет маршрута к внешним адресам, трассировка через него, скорее всего, остановится в локальной сети;
- у туннелей показан процесс-владелец (например,
xray) и физический адаптер, через который туннель работает.
Управление с клавиатуры: ↑ ↓ выбор, Enter подтвердить, Esc закрыть (если трассировка уже идёт). Отключённые и служебные адаптеры спрятаны под ссылкой «Показать отключённые и служебные».
Почему у Ethernet трафика больше, чем у VPN-туннеля? Туннель не имеет своего провода: зашифрованный трафик VPN физически идёт через Ethernet или Wi-Fi. Поэтому счётчики физического адаптера всегда включают в себя весь трафик туннеля.
Интерфейс
Командная строка
Поле цели понимает всё, что обычно копируют:
| Ввод | Как разбирается |
|---|---|
1.1.1.1, 2606:4700:4700::1111 | IP-адрес, DNS не нужен |
google.com, яндекс.рф | домен; кириллица переводится в punycode |
https://site.ru/path?q=1 | берётся хост, порт по схеме (443 для https) идёт в TCP-пинг |
host:8080, [::1]:443 | хост и порт |
user@host | берётся хост |
Справа от поля: Старт или Стоп, Пауза, Сброс (начать заново с нуля), параметры зондирования, чип адаптера (открывает выбор адаптера), переключатель VPN-режима (только для туннелей) и экспорт.
Горячие клавиши
| Клавиши | Действие |
|---|---|
| Ctrl+L или F6 | перейти в поле цели |
| Enter | запустить трассировку |
| ↑ ↓ | выбор из недавних целей |
| Esc | закрыть подсказки, меню, окно адаптеров |
Области окна
- Таблица хопов слева, под ней строки разбора («Маршрут стабилен», «Потери начинаются на хопе N» и т.п.).
- Карта справа: сводка пути сверху, переключатели плоская карта / глобус / подробная онлайн-подложка / показать весь маршрут.
- Нижняя панель: Пакеты, События, Задержка во времени, Соединения процессов, Сведения.
- Строка состояния: состояние, адрес источника и цели, раунд, время, итог по цели, состояние гео-базы.
- Вкладки вида в заголовке: Трассировка и История.
Границы областей перетаскиваются мышью, размеры запоминаются.
Таблица хопов
Одна строка на каждый TTL. Набор колонок настраивается кнопкой в правом верхнем углу таблицы. Все задержки в миллисекундах; точность отображения зависит от величины: 0.94, 4.21, 32.4, 145.
| Колонка | Смысл и формула |
|---|---|
| # | номер хопа (TTL). У цели номер подсвечен. |
| Узел | имя по обратному DNS и IP ответившего роутера. «+N» значит, что на этом TTL отвечали ещё N других узлов. «Нет ответа»: роутер не отвечает на ICMP. |
| Сеть · место | автономная система (AS) и владелец, город и страна. «≈»: место по одному источнику; «?»: место не сходится с измеренной задержкой; anycast: адрес обслуживается во многих местах. |
| Loss% | (Sent − Recv) / Sent × 100 |
| Sent, Recv | отправлено пакетов с этим TTL и получено ответов |
| Last | RTT последнего ответа |
| Avg | среднее арифметическое RTT (считается по Велфорду, без накопления ошибки) |
| Best, Worst | минимальный и максимальный RTT |
| StDev | выборочное стандартное отклонение: √(Σ(x − avg)² / (n − 1)) |
| Gmean | среднее геометрическое: exp(Σ ln x / n); меньше чувствительно к редким выбросам |
| Jttr | текущий джиттер: |RTTₙ − RTTₙ₋₁| |
| Javg | среднее значение джиттера по всем парам соседних ответов |
| Jmax | наибольший джиттер |
| Jint | межпакетный джиттер по RFC 3550: J += (|D| − J) / 16; сглаженная оценка, как в RTP |
| История | полоска последних 60 пакетов: высота столбика = RTT, цвет = зона задержки, красный столбик = потеря |
Цвет задержки: зелёный до 30 мс, салатовый 30–60, жёлтый 60–100, оранжевый 100–180, красный больше 180. Потери: серым 0%, жёлтым до 5%, красным от 5%.
Подробности хопа
Клик по строке раскрывает детали: график последних 120 пакетов и сводка (min, avg, max, σ, Jint, Jmax), IP и имя, AS с источником данных, префикс и регистратор, провайдер, место с координатами, решение геолокации и физический предел расстояния, последний статус ICMP. Ниже показано, что сказал каждый источник геолокации и почему его приняли или отклонили, с датой получения данных. Если на хопе отвечает несколько узлов, видна доля каждого.
Правая кнопка мыши по строке: трассировать до этого узла, показать подробности, скопировать IP, имя или всю строку.
Сколько строк показывается
Пока цель не ответила, видны хопы до последнего ответившего плюс один (через три раунда плюс три), чтобы было видно, где маршрут обрывается. Когда цель ответила на TTL k, хопы дальше k скрываются и больше не опрашиваются. Если роутер трижды сообщил «недоступно» (сеть, узел, запрещено), маршрут считается законченным на нём.
Как читать результаты
Главное правило MTR: значение имеет только то, что сохраняется до цели. Роутеры обрабатывают ответы на ICMP по остаточному принципу, поэтому их собственные потери и задержки часто выше, чем у транзитного трафика.
| Картина | Что это значит |
|---|---|
| Потери на хопе 4, дальше 0% | ограничение ICMP на роутере, на трафик не влияет |
| Потери начинаются на хопе N и держатся до цели | вероятное место проблемы: канал или узел N (или ответный путь) |
| Хоп «Нет ответа», дальше всё отвечает | роутер не отвечает на ICMP, трафик пропускает; нормально |
| Резкий рост задержки между хопами и дальше не падает | длинный магистральный участок (например, между странами) или перегрузка |
| Задержка выросла на хопе и упала на следующем | медленный ответ самого роутера, не проблема |
| Высокий Javg у цели | нестабильная задержка: заметно в играх и звонках |
| Цель не отвечает на ICMP, TCP-пинг отвечает | узел доступен, ICMP фильтруется |
| Цель «отвечает» на первом хопе за доли миллисекунды | ответы подделывает VPN-туннель, нужен VPN-режим |
Помните про асимметрию: путь туда и обратно может проходить через разные узлы. Таблица показывает путь туда, а задержка включает оба направления.
Автоматический разбор
Под таблицей программа пишет выводы по этим правилам. Выводы обновляются раз в секунду и учитывают хопы, по которым накоплено не меньше 10 пакетов. Полный список в разделе События и выводы.
Параметры зондирования
Открываются кнопкой с ползунками рядом с полем цели. Изменения применяются при следующем запуске или по кнопке «Перезапустить».
| Параметр | По умолчанию | Диапазон | Смысл |
|---|---|---|---|
| Интервал | 1000 мс | 100–60 000 | пауза между раундами на каждом хопе |
| Таймаут | 2000 мс | 200–10 000 | сколько ждать ответа на пакет; дольше значит «потерян» |
| Размер пакета | 64 Б | 0–65 000 | полезная нагрузка ICMP |
| Макс. хопов | 30 | 1–64 | предельный TTL |
| Пакетов за раунд | 1 | 1–20 | серия пакетов на каждый хоп в раунде |
| Раундов | 0 | 0–1 000 000 | 0 = бесконечно, иначе остановка после N раундов |
| Протокол IP | Авто | Авто, IPv4, IPv6 | Авто предпочитает IPv4, если у домена есть оба адреса |
| Запрет фрагментации (DF) | выкл | для поиска проблем с MTU: большой пакет с DF вернёт «пакет больше MTU» | |
| Имена узлов | вкл | обратный DNS для каждого хопа | |
| TCP-пинг, если цель молчит | вкл, порт 443 | 1–65535 | см. TCP-фолбэк |
| Онлайн-уточнение | вкл | RIPE IPmap, RIPEstat, ip-api.com, Cloudflare; выключите для полностью офлайн-работы | |
| Содержимое пакета | MTRTracer | до 64 символов | чем заполняется нагрузка ICMP |
Как работает зондирование
Потоки и раунды
На каждый TTL от 1 до максимума запускается свой поток. Поток отправляет пакет (или серию), ждёт ответ не дольше таймаута, затем выдерживает паузу до конца интервала. Старт потоков разнесён на несколько миллисекунд, чтобы 30 пакетов не уходили в одну микросекунду и не упирались в ограничения роутеров. Снимок статистики отправляется в интерфейс не чаще 10 раз в секунду.
Windows
Используется системный ICMP API IcmpSendEcho2Ex (IPv6: Icmp6SendEcho2) в синхронном режиме. Он позволяет задать TTL, флаг DF и адрес источника, поэтому привязка к адаптеру работает без прав администратора. RTT меряется высокоточным таймером (Stopwatch) в микросекундах; время ядра в миллисекундах тоже пишется в лог. Таймер включает около 0.1 мс накладных расходов API.
Linux
Основной способ: непривилегированные ping-сокеты (SOCK_DGRAM + IPPROTO_ICMP), их разрешает настройка net.ipv4.ping_group_range. TTL задаётся опцией сокета, а ответы роутеров «TTL истёк» и «недоступно» приходят в очередь ошибок сокета (IP_RECVERR, чтение через recvmsg(MSG_ERRQUEUE)) вместе с адресом роутера. Если ping-сокеты запрещены, программа пробует raw-сокет (нужно право cap_net_raw) и сама разбирает цитату исходного пакета в ответе. Если не разрешено ни то ни другое, трассировка не стартует и показывает, какую команду выполнить.
Определение цели
Цель считается достигнутой на минимальном TTL, на котором пришёл эхо-ответ от её адреса. Хопы дальше этого TTL перестают опрашиваться и скрываются.
TCP-фолбэк
Если через 4 раунда цель так и не ответила на ICMP, включается TCP-пинг: время установки TCP-соединения с портом из параметров (по умолчанию 443), затем 80 и 22, если предыдущий порт дважды не ответил. Отказ в соединении (RST) тоже считается ответом: узел доступен, порт просто закрыт. Результат показывается отдельной строкой «TCP» под таблицей.
Path MTU
Кнопка во вкладке «Сведения» ищет наибольший пакет, который доходит до цели без фрагментации: двоичный поиск от 576 (IPv6: 1280) до 9000 байт с флагом DF, по две попытки на размер. Значение меньше 1500 обычно означает туннель, PPPoE или VPN.
Обрыв сети
Программа следит за изменениями сетевых адресов. Если выбранный адаптер отключился или потерял адрес, трассировка встаёт на паузу, сверху появляется баннер с таймером, событие пишется в лог. Раз в секунду проверяется, вернулась ли сеть; затем трассировка продолжается сама, привязавшись к новому адресу того же адаптера.
Карта и геолокация
Источники
Для каждого публичного адреса собираются мнения нескольких независимых источников. У каждого видна дата получения данных.
| Источник | Вес | Что это | Обновление и кеш |
|---|---|---|---|
| RIPE IPmap | 6 | геолокация инфраструктуры по замерам задержек RIPE Atlas, краудсорсингу и DNS; помечает anycast | кеш 7 дней |
| Cloudflare colo | 6 | для сайтов за Cloudflare: какой дата-центр ответил на /cdn-cgi/trace | при каждой сессии |
| Имя роутера | 5 | коды городов и аэропортов в обратном DNS: fra, ams, waw, frankfurt1 | сразу после PTR |
| MaxMind GeoLite | 3 | через RIPEstat, без ключа | обновляется еженедельно, кеш 7 дней |
| DB-IP Lite | 2 | офлайн-база, работает без интернета | новый выпуск раз в месяц |
| ip-api.com | 1.5 | провайдер и организация, запасной вариант места | кеш 30 дней |
Проверка по скорости света
Свет в оптоволокне проходит около 200 000 км/с, то есть за 1 мс RTT сигнал успевает уйти не дальше примерно 100 км и вернуться. Для каждого кандидата проверяются два условия:
радиус: d(вы, узел) ≤ 100 км × мин. RTT(этого и всех следующих хопов) + 60 км объезд: d(вы, пред.) + d(пред., узел) ≤ 100 км × RTT + 180 км
В радиусе берётся минимум по этому и всем следующим хопам: пакеты к дальним хопам проходят через этот узел, поэтому их быстрый ответ тоже ограничивает его расстояние. Это защищает от медленных ответов роутеров. Учитываются только хопы, по которым пришло хотя бы 2 ответа. «Объезд» требует, чтобы путь через предыдущий размещённый узел тоже укладывался в задержку; это убирает зигзаги.
Выбор и статусы
Из прошедших проверку кандидатов выбирается лучший по весу источника, плюс 1.5 за каждый другой источник в пределах 120 км, минус 3, если известна только страна.
| Статус | На карте | Когда |
|---|---|---|
| подтверждено | сплошная точка | город совпал у двух источников или пришёл от RIPE IPmap / Cloudflare |
| один источник | кольцо, «≈» | место прошло проверку, но подтверждено одним источником или только страна |
| anycast | пунктирное кольцо | все кандидаты физически невозможны, а адрес anycast (Cloudflare, Google DNS, Quad9 и др.); ставится у ближайшего подтверждённого узла |
| не сходится с RTT | кольцо с жёлтым ореолом, «?» | все источники противоречат задержке; показан самый надёжный из них как есть |
| локальная сеть | в точке «Вы» | частные адреса, CGNAT провайдера |
Точка «не сходится с RTT» не используется как опора для проверки следующих хопов, чтобы одна ошибочная база не тянула за собой весь маршрут.
Сводка над картой
Число точек, длина пути по участкам, расстояние по прямой до цели, физический минимум RTT (расстояние × 2 / 200 000 км/с) и измеренный RTT с коэффициентом «во сколько раз путь длиннее идеального». Минимум считается только для подтверждённой цели, поэтому противоречие «измерено меньше физического минимума» невозможно.
Подложка и проекции
По умолчанию карта полностью офлайн: границы стран Natural Earth встроены в программу (упрощённые на мелком масштабе, подробные на крупном). Кнопкой со слоями включается подробная подложка OpenFreeMap из интернета. Есть плоская проекция и глобус. Анимация пакетов рисуется отдельным слоем и ставится на паузу, когда окно свёрнуто.
Ваше местоположение
Все проверки расстояний считаются от точки «Вы». Источники по приоритету:
- Вручную: город, выбранный во вкладке «Сведения» → «Ваше местоположение». Самый надёжный вариант, без запросов в сеть.
- Cloudflare:
speed.cloudflare.com/metaс адреса физического адаптера (не через VPN). Возвращает ваш публичный IP, провайдера, город, координаты и ближайший дата-центр Cloudflare. Результат действует час и только для текущего адаптера и режима. - Первый узел провайдера: если точки нет, отсчёт идёт от первого публичного хопа с надёжным местом.
Защита от подмены местом VPN
- Адрес Cloudflare резолвится через DNS самого физического адаптера: VPN-клиенты подменяют системный DNS и могут вернуть адреса, работающие только внутри туннеля.
- Если Cloudflare видит в ответе адрес сервера VPN, место отбрасывается: запрос ушёл в туннель.
- Если запрос через туннель и напрямую показывает один и тот же IP, место оставляется, но дополнительно проверяется по задержке.
- Самопроверка: первый близкий публичный роутер (RTT до 30 мс) с надёжным местом должен находиться в пределах физического радиуса от «Вы». Если нет, «Вы» переносится к этому роутеру, а над таблицей появляется предупреждение. Город, указанный вручную, не переносится, только предупреждение.
VPN-режим
Зачем он нужен
Прокси-туннели (Xray, V2Ray, sing-box, Clash/Mihomo, Hiddify, NekoRay, tun2socks) принимают трафик на виртуальный адаптер и передают серверу только TCP и UDP-потоки. Пакет с малым TTL не уходит дальше вашего компьютера, а на эхо-запрос туннель часто отвечает сам за доли миллисекунды. Обычная трассировка через такой адаптер показывает либо одни таймауты, либо «цель на первом хопе за 0.1 мс». Программа это распознаёт (событие «ответы подделаны туннелем») и предлагает VPN-режим.
Как он работает
- По таблице соединений ищется процесс известного VPN-клиента и его TCP-соединения с физического адаптера; адрес с наибольшим числом соединений считается сервером. Если не угадал, сервер вписывается вручную во вкладке «Сведения».
- До сервера VPN идёт обычная трассировка через физический адаптер: это настоящие хопы вашего провайдера и магистралей.
- До самой цели через туннель держится одно постоянное HTTPS-соединение (или HTTP на порту 80, если 443 не отвечает), и раз в интервал отправляется маленький запрос
HEAD /. Время от запроса до первого байта ответа и есть настоящая сквозная задержка: этот путь действительно проходит туннель, сервер VPN и интернет до цели. - Через туннель запрашивается Cloudflare, чтобы показать выход VPN: IP, провайдера, город и дата-центр.
- Оценка участка «сервер → цель» = минимальный сквозной RTT − минимальный RTT до сервера.
Что видно в интерфейсе
- Над таблицей: «Через Ethernet: настоящие хопы до сервера VPN …».
- После хопов строка «Туннель»: IP выхода, провайдер, город, дата-центр Cloudflare и оценка «сервер → цель».
- Строка цели через туннель: Loss%, Sent, Last, Avg, Best, Worst, Javg, история.
- На карте: дом → хопы → сервер VPN (квадрат) → пунктирная дуга туннеля → цель.
TCP-соединение через прокси-туннель «устанавливается» за доли миллисекунды: его подтверждает сам туннель. Поэтому VPN-режим меряет задержку по ответу на HTTP-запрос, а не по TCP-рукопожатию. Программа показывает отдельно и время установки TLS.
Ограничения
- Хопы за сервером VPN не видны никак: это свойство туннеля.
- UDP-протоколы (WireGuard, Hysteria, TUIC) не видны в таблице TCP-соединений: укажите сервер вручную.
- Если цель не отвечает ни на 443, ни на 80, сквозная задержка не измеряется.
- Трассировка до сервера VPN идёт с реального IP, тем же путём, которым VPN-клиент и так подключается к серверу.
DNS и сеть узлов
Резолв цели
- Системный резолвер (учитывает hosts, VPN, корпоративные политики), таймаут 4 с.
- Если он не ответил: собственный DNS-клиент по UDP к DNS-серверам адаптера, затем к 1.1.1.1, 8.8.8.8, 9.9.9.9, по 2.5 с на запрос; ответ «домен не существует» останавливает перебор.
Каким путём получен адрес и сколько это заняло, видно во вкладке «Сведения». Там же кнопка «Сравнить DNS-серверы»: параллельный запрос ко всем серверам с временем ответа.
Имена узлов
Обратный DNS (PTR) сначала через систему с таймаутом 2.5 с, затем напрямую к DNS-серверам. Запросы асинхронные и кешируются: зондирование не ждёт имён.
AS, префикс, провайдер
Актуальные данные маршрутизации из RIPEstat (network-info и as-overview), при отсутствии сети офлайн-база DB-IP ASN, затем DNS-интерфейс Team Cymru. Источник подписан в подробностях хопа. Провайдер и организация берутся из ip-api.com.
Лог пакетов и коды ICMP
Вкладка «Пакеты» показывает каждый отправленный пакет. В памяти держится до 100 000 последних строк, на диск пишется всё (см. Файлы). Фильтры: хоп, тип (все, ответы, потери, ошибки ICMP), поиск по IP, статусу или номеру. «Следить» прокручивает к новым пакетам.
| Поле | Смысл |
|---|---|
| Время | момент отправки с миллисекундами |
| Раунд, Seq | номер раунда на этом хопе и сквозной номер пакета |
| TTL | хоп |
| Ответил | адрес ответившего узла, «*» если ответа нет |
| Статус ICMP | расшифровка и числовой код |
| RTT, мс | с тремя знаками после запятой (микросекунды) |
| Ядро | RTT по данным ядра Windows в мс; на Linux округлённый RTT |
| Байт, Источник, Proto | размер нагрузки, адрес источника, протокол (icmp или tcp:порт) |
| Статус | Код | Значение |
|---|---|---|
| ответ цели | 0 | эхо-ответ от цели |
| TTL истёк | 11013 | роутер на этом хопе ответил: время жизни пакета истекло |
| таймаут | 11010 | ответа не было за время таймаута |
| сеть недоступна | 11002 | у роутера нет маршрута в сеть цели |
| узел недоступен | 11003 | сеть есть, узла нет |
| протокол недоступен | 11004 | протокол не поддерживается или (IPv6) запрещено |
| порт недоступен | 11005 | для ICMP встречается редко |
| пакет больше MTU | 11009 | с флагом DF пакет не пролезает в канал |
| запрещено фильтром | 11044 | административный запрет |
| ошибка параметров | 11015 | роутер не принял заголовок |
| TCP: порт открыт / отказ / таймаут | строки TCP-пинга |
Коды одинаковы на Windows и Linux: на Linux ответы ICMP переводятся в тот же словарь, чтобы логи и экспорт совпадали.
События и выводы
События
Вкладка «События» хранит всё, что произошло в сессии, с точным временем. Предупреждения и ошибки считаются на значке вкладки.
| Код | Когда появляется |
|---|---|
| start, stopped, finished | старт с параметрами, остановка, завершение после заданного числа раундов |
| destination | цель впервые ответила, с числом хопов |
| route-change | на хопе появился новый узел после того, как маршрут уже устоялся |
| primary-change | основным узлом хопа стал другой адрес |
| loss-burst, recovered | цель не ответила 3 раза подряд; связь восстановилась, с длительностью |
| dest-unreachable | роутер трижды сообщил, что цель недоступна |
| packet-too-big | пакет с DF больше MTU канала |
| tcp-fallback | включён TCP-пинг |
| network-down, network-up, source-changed | обрыв сети, восстановление, смена адреса адаптера |
| dns-fallback | системный DNS не ответил, адрес получен напрямую |
| no-route | у выбранного адаптера нет маршрута до цели |
| fake-replies | ответы подделаны VPN-туннелем |
| icmp-permission | нет прав на ICMP (Linux) |
| resolve-failed, bad-target, adapter-down, no-address | ошибки запуска |
Выводы анализатора
| Вывод | Правило |
|---|---|
| Маршрут стабилен | до цели меньше 1% потерь, нет ошибок и сильного джиттера |
| Потери начинаются на хопе N | у цели от 3% потерь; первый хоп с потерями от 3%, после которого все хопы держат не меньше 60% этих потерь |
| Ограничение ICMP на роутере | у хопа от 5% потерь, а дальше есть хоп с потерями меньше вдвое |
| Хоп не отвечает, но пропускает | не меньше 5 пакетов без ответа, а следующие хопы отвечают |
| Рост задержки | скачок средней задержки от 25 мс, который не спадает к цели (дальше не ниже чем на 10 мс) |
| Высокий джиттер | средний джиттер до цели больше 10 мс |
| ICMP фильтруется | цель молчит на ICMP, но отвечает TCP-пинг |
| Ответы подделаны туннелем | см. VPN-режим |
| В прошлый раз | если цель есть в истории: время, адаптер и итог прошлого запуска рядом с текущим значением |
Соединения процессов
Вкладка показывает, какие программы держат TCP и UDP-сокеты: процесс и PID, протокол, локальный и удалённый адрес, имя хоста, страну, город и сеть удалённой стороны (по офлайн-базе), состояние, интерфейс и сколько соединение открыто. Обновляется раз в секунду, пока вкладка открыта. «Только интернет» скрывает слушающие сокеты и локальную сеть. «Журнал» показывает открытия и закрытия.
Правая кнопка мыши по строке: трассировать до этого адреса (обычно или через VPN), скопировать IP, IP:порт или имя хоста, показать только этот процесс, открыть папку программы.
| Windows | Linux | |
|---|---|---|
| Источник | GetExtendedTcpTable, GetExtendedUdpTable | /proc/net/tcp, tcp6, udp, udp6 и /proc/*/fd |
| Процессы | все, путь к файлу у большинства | свои; процессы других пользователей видны как «другой пользователь» без root |
| Иконки | из exe | нет |
Трафик по отдельным соединениям не показывается: для этого нужны права администратора. Скорость видна по адаптерам в окне выбора адаптера.
История
Каждая трассировка становится записью в журнале. Снимок пишется раз в минуту и при остановке: итог по цели (потери, avg, best, worst, джиттер), полный список хопов и отпечаток маршрута. Запуски без единого снимка (не стартовали) удаляются. Хранение 180 дней.
- Список целей слева: время последней проверки, итог и мини-график средней задержки по запускам. Поиск по имени.
- График средней задержки и потерь по запускам, ось дат.
- Таблица запусков: когда, сколько длился, режим, адаптер и адрес, avg, best, потери, джиттер, число хопов, маршрут. «Изменился» значит, что набор узлов отличается от предыдущего запуска (по отпечатку основных адресов хопов).
- Сравнение: отметьте два запуска. Таблица по TTL: узел и avg/потери в каждом запуске, разница; узлы, которые поменялись, подсвечены.
- Кнопка «Проверить сейчас» запускает новую трассировку этой цели. Правая кнопка мыши: удалить запуск или всю историю цели.
Для VPN-режима в историю пишется сквозная задержка через туннель, а не задержка до сервера.
Настройки и данные
Окно открывается шестерёнкой в заголовке или щелчком по «гео-база …» в строке состояния. Проект выложен как публичный архив, поэтому всё, что со временем устаревает, обновляется отсюда, без новой версии программы.
Общие
- Язык: русский или английский. Переключается сразу; на нём же пишутся разбор маршрута, события и отчёты. По умолчанию берётся язык системы.
- Тема: «как в системе», графит (тёмная), светлая, Catppuccin Mocha, Nord. Карта и графики перекрашиваются вместе с интерфейсом.
Офлайн-база
| Действие | Что происходит |
|---|---|
| Скачать новейшую | самый новый выпуск DB-IP Lite (город и ASN); текущий месяц появляется через несколько дней после начала месяца, поэтому пробуются и предыдущие |
| Проверить | HEAD-запросы к серверу DB-IP за последние 6 месяцев: какие выпуски есть и сколько весят. Сами файлы не скачиваются |
| Закрепить | использовать этот выпуск всегда; автообновление на него не действует |
| Самая новая из установленных | режим по умолчанию: после обновления сразу используется новый выпуск, старые удаляются |
| Своя база | файл .mmdb, .mmdb.gz или .tar.gz (так MaxMind раздаёт GeoLite2) с диска или по ссылке https. Тип определяется по метаданным: база городов или ASN |
| Адрес выпусков DB-IP | шаблон ссылки с {name} и {month}; пригодится, если DB-IP поменяет адрес загрузки |
Подходят базы в формате MaxMind: DB-IP Lite City/ASN, MaxMind GeoLite2 City/ASN (нужна бесплатная регистрация на сайте MaxMind), ASN-база IPinfo.
Источники
Главный выключатель «Онлайн-уточнение» и отдельный переключатель для каждого источника: имена роутеров и офлайн-база (работают без сети), RIPE IPmap, RIPEstat, ip-api.com, Cloudflare meta (ваше место), Cloudflare colo (дата-центр сайта), Team Cymru (AS через DNS). Выключенный источник не получает запросов и не участвует в выборе места. Рядом написано, что именно уходит в сеть. Кнопка «Очистить» стирает кэш ответов; адреса текущего маршрута запрашиваются заново.
Обновления
«Проверить обновления» спрашивает у GitHub последний релиз репозитория и показывает версию, дату, описание и файлы для вашей системы. Программа сама ничего не скачивает и не заменяет: файл открывается в браузере. Если вы пользуетесь форком, впишите его в поле «Откуда брать обновления» в виде владелец/имя.
Экспорт
| Формат | Содержимое |
|---|---|
| Текст .txt | шапка с параметрами и таблица в духе WinMTR, альтернативные узлы, TCP-пинг, выводы |
| Таблица .csv | hop, ip, hostname, asn, as_name, country, city, lat, lon, loss_pct, sent, recv, best/avg/worst/last/stdev/gmean, jitter/javg/jmax/jint, status, alt_responders |
| Отчёт .html | самостоятельная страница с таблицей, выводами и событиями |
| Все пакеты .json | сессия, параметры, снимок хопов, сведения об узлах, все события и все пакеты |
| Копировать как текст | текстовый отчёт в буфер обмена |
На Windows открывается диалог сохранения. На Linux файл сохраняется в папку загрузок (XDG), путь показывается в уведомлении.
Файлы и данные
Папка данных: %LOCALAPPDATA%\MTRTracer на Windows, ~/.local/share/MTRTracer на Linux.
| Путь | Что хранится |
|---|---|
| settings.json | адаптер, VPN-режим и сервер, точка отсчёта, параметры зондирования, недавние цели, язык, тема и прочие настройки интерфейса, включённые источники, выбранная офлайн-база, репозиторий обновлений |
| history.db | история (SQLite): таблицы runs и snapshots |
| sessions/*.ndjson | полный лог каждой сессии: по строке на пакет, событие или служебную запись |
| geo/dbip-*-lite-ГГГГ-ММ.mmdb | офлайн-базы DB-IP (город и ASN), по файлу на выпуск |
| geo/custom-city.mmdb, custom-asn.mmdb | своя база, импортированная в настройках |
| geo/*.json | кеши RIPE IPmap, RIPEstat, ip-api.com |
| logs/errors-ГГГГММДД.log | ошибки программы |
| WebView2/, ui/ | Windows: профиль встроенного браузера и распакованный интерфейс |
Формат строки лога сессии:
{"kind":"probe","data":{"t":1760541600123,"round":12,"seq":330,"ttl":7,"src":"10.0.0.2","dst":"142.250.185.78",
"from":"62.115.137.38","status":"ttl-expired","rawStatus":11013,"rttMs":31.214,"kernelMs":31,"size":64,"proto":"icmp"}}
{"kind":"event","data":{"t":1760541601000,"level":"warn","code":"route-change","message":"…","ttl":7,"ip":"62.115.137.40"}}
Всё можно удалить вместе с папкой: программа создаст её заново.
Приватность
| Что уходит | Куда | Как отключить |
|---|---|---|
| Пакеты трассировки | роутеры по пути, с адреса выбранного адаптера | суть работы; выбор адаптера определяет, какой IP видят роутеры |
| Скачивание DB-IP Lite | download.db-ip.com | нельзя, но это одна загрузка в месяц |
| Адреса узлов маршрута | RIPE IPmap, RIPEstat, ip-api.com | «Онлайн-уточнение» в параметрах |
| Ваше местоположение | Cloudflare, с реального IP физического адаптера | «Онлайн-уточнение» или город вручную |
| Дата-центр цели | сайт цели за Cloudflare (/cdn-cgi/trace) | «Онлайн-уточнение» |
| Подробная подложка карты | tiles.openfreemap.org | не включать кнопку со слоями |
| Сравнение DNS, Path MTU | DNS-серверы, цель | только по кнопке |
Телеметрии и аналитики нет. На Linux локальный сервер интерфейса слушает только 127.0.0.1 и принимает команды только со случайным ключом текущего запуска.
Особенности Linux
Запуск
| Команда | Действие |
|---|---|
mtrtracer | окно приложения (WebKitGTK) |
mtrtracer --browser | интерфейс в браузере по умолчанию; выход Ctrl+C в терминале |
mtrtracer --port 8642 | фиксированный порт локального сервера (по умолчанию случайный) |
mtrtracer --devtools | инспектор WebKit |
mtrtracer --help | справка |
Если WebKitGTK не установлен, программа сама переходит в режим браузера и пишет в терминал, какой пакет поставить.
Права на ICMP
Проверить, разрешены ли ping-сокеты для вашей группы:
cat /proc/sys/net/ipv4/ping_group_range id -g
Если ваш GID попадает в диапазон, всё работает без root. Если нет, один из вариантов:
# разрешить ping-сокеты всем пользователям (до перезагрузки) sudo sysctl -w net.ipv4.ping_group_range="0 2147483647" # навсегда echo 'net.ipv4.ping_group_range = 0 2147483647' | sudo tee /etc/sysctl.d/60-mtrtracer.conf # или дать право на raw-сокеты только программе sudo setcap cap_net_raw+ep ~/.local/opt/mtrtracer/MTRTracer
Право setcap слетает при обновлении файла программы: после переустановки выполните его снова (или ./install.sh --setcap).
Отличия от Windows
- Окно с обычной рамкой системы, без своих кнопок свернуть и закрыть.
- Маршруты и адреса:
ip route get, интерфейсы классифицируются по имени:en*/eth*,wl*,tun*/wg*/tailscale*,docker*/br-*/veth*. - Буфер обмена: браузерный API, иначе
wl-copy,xclipилиxsel. - Экспорт сохраняется в папку загрузок, папки открываются через
xdg-open.
Решение проблем
Через VPN все хопы таймаут
Прокси-туннель не пропускает пакеты с малым TTL. Выберите VPN-адаптер и включите VPN-режим, или выберите физический адаптер (Ethernet, Wi-Fi), чтобы увидеть маршрут мимо VPN.
Цель «отвечает» на первом хопе за 0.1 мс
Ответы подделывает туннель. Включите VPN-режим.
VPN-режим: «не удалось определить сервер VPN»
Клиент работает по UDP или не распознан. Возьмите адрес сервера из настроек VPN-клиента и впишите во вкладке «Сведения» → «Сервер VPN».
На карте почти все точки с «?»
Скорее всего, неверно определена точка «Вы». Укажите свой город вручную во вкладке «Сведения» → «Ваше местоположение».
Linux: «Нет прав на ICMP»
Разрешите ping-сокеты или выдайте cap_net_raw, см. Права на ICMP.
Linux: окно не открывается
Нет WebKitGTK 4.1: установите libwebkit2gtk-4.1-0 (Debian/Ubuntu), webkit2gtk4.1 (Fedora), webkit2gtk-4.1 (Arch) или запускайте с --browser.
Windows: пустое окно или сообщение про WebView2
Установите Microsoft Edge WebView2 Runtime. Если окно сообщает, что интерфейс не встроен, пересоберите через build.ps1.
Exe пропал после сборки
Файл не подписан и работает с сетью на низком уровне; антивирус мог поместить его в карантин. Проверьте журнал защиты и добавьте папку сборки в исключения.
Гео-база не скачалась
Строка состояния покажет ошибку. Повторите кнопкой во вкладке «Сведения» → «Геолокация». Без базы программа работает, места узлов берутся из онлайн-источников или имён роутеров.
Адаптер выбран, но «нет маршрута до цели»
У адаптера нет шлюза в интернет (например, виртуальный адаптер Hyper-V). Выберите другой адаптер или «Авто».
«Пакет больше MTU»
Включён флаг DF, а размер пакета больше MTU канала. Уменьшите размер или снимите DF. Узнать точный MTU поможет кнопка Path MTU.
Архитектура
| Проект | Роль |
|---|---|
| src/MTRTracer.Core | вся сетевая логика, кроссплатформенная: зондирование (Windows ICMP API и Linux-сокеты), сессии MTR, статистика, анализатор, DNS-клиент, геолокация и решатель маршрута, VPN-режим, соединения процессов, история (SQLite), экспорт |
| src/MTRTracer.App | Windows: окно WPF без рамки, WebView2, мост сообщений, диалоги |
| src/MTRTracer.Linux | Linux: локальный HTTP-сервер на 127.0.0.1, мост по WebSocket, окно Photino (WebKitGTK) или браузер |
| src/MTRTracer.Tests | юнит-тесты: статистика, разбор ввода, DNS, геолокация, решатель, разбор ответов источников, история, разбор /proc и ICMP-ошибок Linux |
| ui | интерфейс на React и TypeScript: таблица, карта MapLibre, графики uPlot, история |
Мост между интерфейсом и ядром
Сообщения одинаковые на обеих платформах (через WebView2 на Windows, через WebSocket на Linux):
{"kind":"req","id":7,"type":"trace.start","payload":{"target":"google.com"}}
{"kind":"res","id":7,"ok":true,"result":{"sessionId":"s1-210512"}}
{"kind":"evt","type":"trace.hops","payload":{…}}
Команды: app.info, settings.get/set, adapters.list/select/watch, tunnel.detect, trace.start/stop/pause/reset/pmtu/dnsBench, geo.status/download/self/cities, host.get, connections.subscribe, export.save, history.targets/runs/run/delete, clipboard.copy, shell.open/reveal, process.icon, window.*.
События: trace.state, trace.resolved, trace.hops, trace.probes, trace.event, route.geo, host.info, geo.status, geo.origin, adapters.traffic, connections.snapshot, connections.events, history.previous, history.changed, window.state.
Частые события (снимки хопов, гео, трафик, соединения) объединяются до последнего значения, строки пакетов отправляются пачками, всё остальное по порядку, примерно 20 раз в секунду.
Глоссарий
| Хоп | один роутер на пути пакета |
| TTL | время жизни пакета в хопах; каждый роутер уменьшает его на 1, при нуле пакет отбрасывается и отправителю приходит сообщение |
| RTT | время туда и обратно |
| Джиттер | изменчивость задержки между соседними пакетами |
| ICMP | служебный протокол IP: эхо-запросы, «TTL истёк», «недоступно» |
| ECMP | балансировка по нескольким равноценным путям: на одном хопе отвечают разные узлы |
| AS | автономная система: сеть одного оператора с единой политикой маршрутизации |
| Anycast | один адрес анонсируется из многих мест, отвечает ближайший узел |
| CGNAT | NAT на стороне провайдера, адреса 100.64.0.0/10 |
| MTU, Path MTU | наибольший размер пакета в канале и на всём пути |
| PTR | обратная DNS-запись: имя по IP |
| Прокси-туннель | VPN, который передаёт только TCP/UDP-потоки (Xray, sing-box, Clash); хопы за ним не видны |
Ничего не найдено. Попробуйте другое слово.