Проверка блокировок перестала врать
Самая большая работа этого выпуска, и почти целиком — про честность отчёта.
Шесть жалоб вида «у меня работает, а проверка говорит сломано» разобраны,
и все шесть оказались ошибками проверки, а не обхода.
Разделители подписки больше не попадают в автоподбор. Поставщики кладут
в список строки вроде «Wi-FI сервера» и «Обходы ниже» — заголовки групп
для чужого клиента. Адрес у них нулевой, и когда автоподбор выбирал такой,
всякое соединение обрывалось мгновенно.
Маркеры зон не выдаются за недоставку. Имя без записи A — scdn.co,
spotifycdn.com — напрямую опознавалось сразу, а заведённое в туннель
получало fakeip, и опознание не срабатывало.
Отказ согласования TLS больше не зовётся виной туннеля. Если сторона
ответила отказом, туннель её ответ как раз доставил.
«Через туннель» стало замером, а не обещанием правил. Прежде пометка
ставилась по ответу движка правил, и никто не проверял, что соединение
вправду туда ушло. Пин в hosts бьёт любой резолв — и такие имена шли
напрямую, получая вердикт о трубе.
Перенаправление засчитывается как ответ. 302 — законченный ответ,
у него нет тела, которое можно дочитать.
Несостоявшийся замер не выдаётся за обрыв у сайта. Проба делает
к одному адресу четыре соединения подряд, и часть площадок такую очередь
отшивает; отказ доставался четвёртому при живых первых трёх.
Ещё проверка теперь показывает, что сказал сам движок, умеет пустить имя
в туннель нарочно и перепроверяет в тишине то, что могло провалиться
от тесноты.
Проверка блокировок стала честнее
Восьмидесятый порт спрашивается только когда нужен. Разбор вердикта
смотрит на него ровно в одной ветке — той, где TCP на 443 не поднялся.
Во всех прочих строках колонка показывалась и не значила ничего, а
спрашивался порт всегда: четыре секунды на цель, с повтором восемь, и так
на сотне с лишним имён. В строке при этом стояло «HTTP: RST» рядом
с вердиктом «доступен», и это читалось как противоречие самому себе.
Отказ согласования больше не выдаётся за блокировку. Сторона, не дающая
TLS 1.2, отвечает словами и быстро — это её настройка. Фильтр так
не отвечает: он рвёт соединение либо молчит. Проверено: battle.net,
playstation.com, zoom.com и npmjs.org на 1.3 не отвечают вовсе,
а на 1.2 отдают 301. Такая ячейка теперь «н/д», и имя не идёт в перечень
закрытого.
Причина берётся у той стадии, что решила вердикт. Прежде бралась первая
непустая из пяти, и у имени с убитым рукопожатием в строке оказывался
рассказ про удавшийся TCP — про то, что как раз сработало. Теперь у обрыва
это цифры передачи («поток замер на 26011 Б»), у гео-отказа ответ сайта,
у закрытого маршрута слова TCP.
Маркеры зон вне таблицы. Записи A у scdn.co, playstation.net,
nintendo.net, slack-edge.com и dropboxusercontent.com нет ни у кого:
работают только поддомены. Строка «нет адреса у имени» среди закрытого
сбивала — её начинали чинить. Пропущенные считаются и называются
под таблицей.
Отказ по стране стал жёлтым вместо красного. Это работающая связь:
ответ пришёл, и пришёл от самого сайта.
Имя, выведенное из-под десинка, названо вслух
Прибитое в hosts или поставленное на «напрямую» уходит в исключения,
и winws2 его не трогает вовсе. Отчёт об этом молчал и советовал десинк —
то есть звал чинить то, что по нашему же решению не применяется.
Первый запуск ведёт за руку
Программа не вела нового человека вовсе: он попадал на «Главную» и оставался
один на один с одиннадцатью разделами. Теперь при первом открытии его
встречает мастер из трёх шагов — подписка, пробный запуск, результат.
Пропустить можно любой шаг по отдельности, а не весь мастер разом. Повторить
его — кнопка в «Ещё».
Маршруты: список вместо каталога
Двадцать шесть папок превратились в пятьдесят пять сервисов, и каждый
на виду.
В каталоге лежали два разных вида записей под одним типом. У Discord части —
стороны одного сервиса: голос, переписка, запасной путь; они ломаются врозь,
и папка вокруг них осмысленна. А «Мессенджеры» — это Signal и Viber, два
чужих друг другу сервиса, и общего у них ровно то, что мы положили их
на одну полку. Человек ищет Signal, а не «мессенджеры», и лишний щелчок
стоял между ним и его сервисом.
Двенадцать таких полок раскладываются сразу. Папками остались пять, где
части действительно ломаются врозь: Discord, YouTube, Telegram, Roblox,
Steam. Ещё девять сервисов показываются одной строкой — разворачивать
у них нечего, а стрелка обещала содержимое, которого нет.
Заодно выправлен вид: значки в одну линию, одинаковая высота у всех строк,
один шаг между ними, стрелка крупнее и заметнее. Появилась сортировка
по алфавиту: порядок каталога хорош, пока помнишь его наизусть, и плох,
когда ищешь Zoom среди пятидесяти пяти строк.
Раздел маршрутов перестал тормозить
Подпись «чем именно пойдёт часть» спрашивала пресет на каждую из восьмидесяти
частей, и каждый раз перечитывала все его списки. В russia-blacklist.txt
сто семнадцать тысяч имён — он оказывался прочитан восемьдесят раз подряд.
Теперь списки читаются однажды, а поиск идёт по множеству зон: три проверки
вместо ста семнадцати тысяч сравнений.
Видно, чем именно пойдёт часть
Подпись «десинк» не говорила ничего. Она означает «мимо туннеля, решает
пресет», а решить пресет может и «пропустить», и «не знаю такого имени» —
и всё это выглядело одинаково с работающим правилом.
Теперь в строке стоит приём той секции, до которой дойдёт очередь: winws2
отдаёт пакет первому совпавшему профилю и дальше не смотрит.
десинк: hostfakesplit нашлась секция, чинит этим приёмом
десинк: пресет не чинит имя не попало ни в одну секцию
десинк: пресет пропускает секция нашлась, но в ней «не трогать»
десинк: имя — нет в пресете выбранный рецепт в этом пресете отсутствует
Что открылось сразу: четыре нейросети и полдюжины рабочих сервисов стояли
на десинке, и с ними не делалось ничего.
Название приёма вместо имени секции. Секции пресета названы по тому, что
чинят, и у Speedtest выходило «десинк: rutracker.org» — читалось как ошибка,
хотя это было имя секции, откуда взят рецепт.
Окно выбора рецепта отвечает видимо
Пользователь сказал: «проверка не начинается на твич». Она и не должна
была — twitch.tv открывается без десинка, и окно об этом писало подписью
под заголовком, которую не замечают. Снаружи это выглядело как нажатая
кнопка, после которой ничего не произошло.
Ответ переехал в полосу со значком и цветом: зелёная галочка — имя открыто
и рецепт не нужен, жёлтая пауза — движки работают, красный крест —
проверять нечем.
Появилась кнопка остановки. Перебор идёт до сорока секунд, и прервать его
можно было только закрыв окно, то есть потеряв уже полученные ответы.
Теперь они остаются: «Остановлено. Проверено 3 из 8, ответы сохранены».
Пресет: пять новых секций
У Proton, Signal, Viber, archive.org и Bluesky не было своей секции.
Первых четверых забирала себе секция «Мои сайты» вместе со всем содержимым
lists/other.txt и давала им общий рецепт; Bluesky не покрыт был ничем
вообще — к нему рецепт не применялся ни разу.
Мессенджеры и почту с VPN душат по форме потока, а не по списку имён:
TCP встаёт, а полноценное рукопожатие к тому же адресу глохнет насмерть.
Одно поддельное приветствие такое профилирование не обманывает. Поэтому
hostfakesplit — у него есть подтверждённый прецедент на том же классе.
Замер после правки: Signal, Viber и archive.org открылись. Proton
и Bluesky — нет, им нужен другой рецепт.
Три поломки
Автозапуск. Задача в планировщике возвращала код 2, и это был не сбой
запуска, а ответ самой программы: проверка на незнакомый ключ отвергала
всё, что начинается с двух дефисов и не разобрано выше неё, а --tray
разбирается ниже. Программа не знала собственного ключа. Увидеть это можно
было только в планировщике — окно с жалобой в сеансе автозапуска показывать
некому.
Чтение подписок висело. Таймаут был тридцать секунд на подписку,
читаются они по очереди, а прервать чтение было нечем вовсе. Теперь
двенадцать секунд, отмена работает, и в строке виден номер: «Читаю подписку
2 из 3».
«Замерить все» работало через раз. Источник отмены был один на два
действия, и раздел, перечитывая подписки при каждом заходе, отменял этим
замер, начатый секундой раньше.
Значки не пропадают после перезапуска
Сохранялись они и раньше — восемьдесят пять файлов в runtime\icons. Но
чтение при сборке строки смотрело только в память, а она после запуска
пуста: список открывался буквами и наливался значками секунду спустя.
Теперь при промахе памяти читается диск.
Заодно перестали спрашивать значки у подсетей: у 95.101.173.0/24 его нет
и быть не может, а сетевой запрос уходил.
Мелочи, которых не хватало
Кнопка «открыть в редакторе» на вкладке «Десинк» — пресет правится руками,
а путь до файла проходился каждый раз заново.
Выпуск убирает за собой распакованную копию в dist\: она устаревала
в тот же день, а выглядела так же, как рабочая.
Чего в этом выпуске нет
Сказано прямо, чтобы не искали.
Наше приветствие TLS не такое, как у браузера. Замерено: у speedtest.net
и i.scdn.co собранное по образцу Chrome приветствие принимают, а наше
отвергают. Такие строки теперь так и называются — «наше приветствие TLS
отвергнуто», — но сама проба пока шлёт прежнее. Это самое крупное
из оставшегося.
Proton, Bluesky, SoundCloud и Amazon не берёт ни один из восьми
рецептов. У первых двух теперь хотя бы есть своя секция, и видно,
что именно не сработало.
Чем это собрано и как сверить
NetZapret.zip 2C10CD27472C21EC05F7420E1DE5E50FB4886D6C662776482B61B52D32EBC7D9
NetZapret.exe E73326F607A674F038AF7495FAE1F1C0DFC85D1367F30A5CB60F8F3D6051E347
Пакет SDK .NET 8.0.424, сборка Release, win-x64, self-contained, один файл.
Проверить скачанное:
Get-FileHash NetZapret.zip -Algorithm SHA256
Собрать самому и сравнить:
git checkout v0.6.0
pack.cmd
Совпасть должен NetZapret.exe. Архив — нет: в нём лежат winws2 и sing-box,
собранные не нами, и их версии у вас могут отличаться.