fix: parental control global network block, luci save&apply reload, and fuzzer localization
This commit is contained in:
+1428
-1265
File diff suppressed because it is too large
Load Diff
@@ -9240,3 +9240,75 @@ msgstr ""
|
||||
#: src/tachyon/tabs/diagnostic/checks/runZapret2Check.ts:115
|
||||
msgid "Zapret2 sing-box route rules are not configured"
|
||||
msgstr ""
|
||||
|
||||
msgid "+ add"
|
||||
msgstr ""
|
||||
|
||||
msgid "⚠️ Server received fakes"
|
||||
msgstr ""
|
||||
|
||||
msgid "✓ 32KB Streamed"
|
||||
msgstr ""
|
||||
|
||||
msgid "✗ Throttled at 16KB"
|
||||
msgstr ""
|
||||
|
||||
msgid "Analysis inconclusive."
|
||||
msgstr ""
|
||||
|
||||
msgid "Blocked Sites (Only block domains specified below)"
|
||||
msgstr ""
|
||||
|
||||
msgid "DNS Blocking"
|
||||
msgstr ""
|
||||
|
||||
msgid "DNS resolution failed — likely DNS-level blocking or hijacking."
|
||||
msgstr ""
|
||||
|
||||
msgid "DPI bandwidth throttling or delay detected — connection throttled during data transfer."
|
||||
msgstr ""
|
||||
|
||||
msgid "endpoints OK"
|
||||
msgstr ""
|
||||
|
||||
msgid "IP Block (TCP SYN Timeout)"
|
||||
msgstr ""
|
||||
|
||||
msgid "IP-level blocking detected! The resource is blocked at the network level (no TCP SYN response). DPI bypass methods (Zapret / ByeDPI) cannot bypass this address — configure proxy/VPN routing (Sing-box) for this domain!"
|
||||
msgstr ""
|
||||
|
||||
msgid "No Blocking Detected"
|
||||
msgstr ""
|
||||
|
||||
msgid "Target accessible — no DPI blocking detected."
|
||||
msgstr ""
|
||||
|
||||
msgid "TCP connect timed out before TLS handshake — host is blocked at the IP layer. DPI bypass cannot unblock this; route via Sing-box VPN/Proxy outbound instead."
|
||||
msgstr ""
|
||||
|
||||
msgid "TCP Reset Injection"
|
||||
msgstr ""
|
||||
|
||||
msgid "TCP RST received from DPI — active TCP reset injection detected."
|
||||
msgstr ""
|
||||
|
||||
msgid "Testing:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Throttling / Deep Inspection"
|
||||
msgstr ""
|
||||
|
||||
msgid "Unknown DPI Pattern"
|
||||
msgstr ""
|
||||
|
||||
msgid "Zapret v1"
|
||||
msgstr ""
|
||||
|
||||
msgid "Zapret v2"
|
||||
msgstr ""
|
||||
|
||||
msgid "Allow only: "
|
||||
msgstr ""
|
||||
|
||||
msgid "Block: "
|
||||
msgstr ""
|
||||
|
||||
@@ -855,7 +855,7 @@ msgid "Cache file path cannot be empty"
|
||||
msgstr "Путь к файлу кэша не может быть пустым"
|
||||
|
||||
msgid "Camou"
|
||||
msgstr ""
|
||||
msgstr "Camou"
|
||||
|
||||
msgid "Cancel"
|
||||
msgstr "Отмена"
|
||||
@@ -870,7 +870,7 @@ msgid "Cannot save settings"
|
||||
msgstr "Не удалось сохранить настройки"
|
||||
|
||||
msgid "Captive"
|
||||
msgstr ""
|
||||
msgstr "Captive"
|
||||
|
||||
msgid "Cascade connection"
|
||||
msgstr "Каскадное подключение"
|
||||
@@ -993,7 +993,7 @@ msgid "Click to show"
|
||||
msgstr "Нажмите, чтобы показать"
|
||||
|
||||
msgid "Client"
|
||||
msgstr ""
|
||||
msgstr "Клиент"
|
||||
|
||||
msgid "Client Address"
|
||||
msgstr "Адрес клиента"
|
||||
@@ -1263,7 +1263,7 @@ msgid "Dedicated cgroup unavailable"
|
||||
msgstr "Выделенная cgroup недоступна"
|
||||
|
||||
msgid "Default"
|
||||
msgstr ""
|
||||
msgstr "По умолчанию"
|
||||
|
||||
msgid "Default (auto)"
|
||||
msgstr "По умолчанию (авто)"
|
||||
@@ -2130,7 +2130,7 @@ msgid "France (fr)"
|
||||
msgstr "Франция (fr)"
|
||||
|
||||
msgid "Freedom"
|
||||
msgstr ""
|
||||
msgstr "Freedom"
|
||||
|
||||
msgid "Fri"
|
||||
msgstr "Пт"
|
||||
@@ -2787,7 +2787,7 @@ msgid "Japan (jp)"
|
||||
msgstr "Япония (jp)"
|
||||
|
||||
msgid "Jitsi"
|
||||
msgstr ""
|
||||
msgstr "Jitsi"
|
||||
|
||||
msgid "JSON outbound"
|
||||
msgstr "JSON outbound"
|
||||
@@ -5649,10 +5649,10 @@ msgid "When switching to another level, test every server and select the fastest
|
||||
msgstr "При переключении на другой уровень тестировать каждый сервер и выбирать самый быстрый вместо первого рабочего."
|
||||
|
||||
msgid "WHEP"
|
||||
msgstr ""
|
||||
msgstr "WHEP"
|
||||
|
||||
msgid "WHIP"
|
||||
msgstr ""
|
||||
msgstr "WHIP"
|
||||
|
||||
msgid "Why Discord fails?"
|
||||
msgstr "Почему не работает Discord?"
|
||||
@@ -5670,7 +5670,7 @@ msgid "working strategies"
|
||||
msgstr "рабочих стратегий"
|
||||
|
||||
msgid "WRT"
|
||||
msgstr ""
|
||||
msgstr "WRT"
|
||||
|
||||
msgid "XHTTP mode"
|
||||
msgstr "Режим XHTTP"
|
||||
@@ -6505,3 +6505,75 @@ msgstr "Скачивание и обработка списков"
|
||||
|
||||
msgid "Applying rules and subnet lists"
|
||||
msgstr "Применение правил и списков подсетей"
|
||||
|
||||
msgid "+ add"
|
||||
msgstr "+ добавить"
|
||||
|
||||
msgid "⚠️ Server received fakes"
|
||||
msgstr "⚠️ Сервер получил фейки"
|
||||
|
||||
msgid "✓ 32KB Streamed"
|
||||
msgstr "✓ 32KB Прокачано"
|
||||
|
||||
msgid "✗ Throttled at 16KB"
|
||||
msgstr "✗ Задушено на 16KB"
|
||||
|
||||
msgid "Analysis inconclusive."
|
||||
msgstr "Анализ не дал однозначного результата."
|
||||
|
||||
msgid "Blocked Sites (Only block domains specified below)"
|
||||
msgstr "Заблокированные сайты (Блокировать только указанные домены)"
|
||||
|
||||
msgid "DNS Blocking"
|
||||
msgstr "Блокировка DNS"
|
||||
|
||||
msgid "DNS resolution failed — likely DNS-level blocking or hijacking."
|
||||
msgstr "Сбой разрешения DNS — вероятно, блокировка или перехват на уровне DNS."
|
||||
|
||||
msgid "DPI bandwidth throttling or delay detected — connection throttled during data transfer."
|
||||
msgstr "Обнаружено замедление DPI — соединение заблокировано или задушено при передаче данных."
|
||||
|
||||
msgid "endpoints OK"
|
||||
msgstr "эндпоинтов доступно"
|
||||
|
||||
msgid "IP Block (TCP SYN Timeout)"
|
||||
msgstr "Блокировка по IP (Таймаут TCP SYN)"
|
||||
|
||||
msgid "IP-level blocking detected! The resource is blocked at the network level (no TCP SYN response). DPI bypass methods (Zapret / ByeDPI) cannot bypass this address — configure proxy/VPN routing (Sing-box) for this domain!"
|
||||
msgstr "Обнаружена блокировка по IP! Ресурс блокируется на сетевом уровне (нет ответа на TCP SYN). Методы обхода DPI (Zapret / ByeDPI) бессильны для этого адреса — настройте маршрутизацию через прокси/VPN (Sing-box) для данного домена!"
|
||||
|
||||
msgid "No Blocking Detected"
|
||||
msgstr "Блокировка не обнаружена"
|
||||
|
||||
msgid "Target accessible — no DPI blocking detected."
|
||||
msgstr "Цель доступна — блокировок DPI не обнаружено."
|
||||
|
||||
msgid "TCP connect timed out before TLS handshake — host is blocked at the IP layer. DPI bypass cannot unblock this; route via Sing-box VPN/Proxy outbound instead."
|
||||
msgstr "Таймаут TCP-подключения до рукопожатия TLS — узел заблокирован на уровне IP. Методы обхода DPI не помогут; настройте маршрутизацию через прокси/VPN Sing-box."
|
||||
|
||||
msgid "TCP Reset Injection"
|
||||
msgstr "Внедрение пакетов TCP Reset (RST)"
|
||||
|
||||
msgid "TCP RST received from DPI — active TCP reset injection detected."
|
||||
msgstr "Получен TCP RST от ТСПУ/DPI — зафиксирована активная инъекция сброса соединения."
|
||||
|
||||
msgid "Testing:"
|
||||
msgstr "Тестирование:"
|
||||
|
||||
msgid "Throttling / Deep Inspection"
|
||||
msgstr "Замедление / Глубокий анализ пакетов"
|
||||
|
||||
msgid "Unknown DPI Pattern"
|
||||
msgstr "Неизвестный тип DPI"
|
||||
|
||||
msgid "Zapret v1"
|
||||
msgstr "Zapret v1"
|
||||
|
||||
msgid "Zapret v2"
|
||||
msgstr "Zapret v2"
|
||||
|
||||
msgid "Allow only: "
|
||||
msgstr "Разрешить только: "
|
||||
|
||||
msgid "Block: "
|
||||
msgstr "Блокировать: "
|
||||
|
||||
@@ -623,7 +623,7 @@ export function renderStrategyFuzzerModal(ruleNames: string[] = []) {
|
||||
const input = E('input', {
|
||||
type: 'text',
|
||||
class: 'cbi-input-text',
|
||||
placeholder: '+ add',
|
||||
placeholder: _('+ add'),
|
||||
style: 'width: 80px; padding: 2px 6px; font-size: 11px;',
|
||||
});
|
||||
|
||||
@@ -888,9 +888,9 @@ export function renderStrategyFuzzerModal(ruleNames: string[] = []) {
|
||||
style: 'flex: 0 1 140px; min-width: 120px;',
|
||||
},
|
||||
[
|
||||
E('option', { value: 'zapret2' }, 'Zapret v2'),
|
||||
E('option', { value: 'zapret' }, 'Zapret v1'),
|
||||
E('option', { value: 'byedpi' }, 'ByeDPI'),
|
||||
E('option', { value: 'zapret2' }, _('Zapret v2')),
|
||||
E('option', { value: 'zapret' }, _('Zapret v1')),
|
||||
E('option', { value: 'byedpi' }, _('ByeDPI')),
|
||||
],
|
||||
);
|
||||
const argsInput = E('input', {
|
||||
@@ -1417,7 +1417,7 @@ export function renderStrategyFuzzerModal(ruleNames: string[] = []) {
|
||||
'Data transfer verified: streamed >= 32KB without throttling or disconnect',
|
||||
),
|
||||
},
|
||||
'✓ 32KB Прокачано',
|
||||
_('✓ 32KB Streamed'),
|
||||
),
|
||||
);
|
||||
} else if (item.dpi_verdict === 'throttled_16k') {
|
||||
@@ -1432,7 +1432,7 @@ export function renderStrategyFuzzerModal(ruleNames: string[] = []) {
|
||||
'DPI throttling: stream cut off after ~16KB payload transfer',
|
||||
),
|
||||
},
|
||||
'✗ Задушено на 16KB',
|
||||
_('✗ Throttled at 16KB'),
|
||||
),
|
||||
);
|
||||
} else if (item.dpi_verdict === 'server_fakes') {
|
||||
@@ -1447,7 +1447,7 @@ export function renderStrategyFuzzerModal(ruleNames: string[] = []) {
|
||||
'Fake packets reached remote server (HTTP 400 Bad Request)',
|
||||
),
|
||||
},
|
||||
'⚠️ Сервер получил фейки',
|
||||
_('⚠️ Server received fakes'),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -1459,7 +1459,7 @@ export function renderStrategyFuzzerModal(ruleNames: string[] = []) {
|
||||
E(
|
||||
'div',
|
||||
{ style: 'font-size: 10px; opacity: 0.75; margin-top: 2px;' },
|
||||
`${passedSub}/${totalSub} endpoints OK`,
|
||||
`${passedSub}/${totalSub} ` + _('endpoints OK'),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -1624,7 +1624,7 @@ export function renderStrategyFuzzerModal(ruleNames: string[] = []) {
|
||||
|
||||
if (currentStratEl) {
|
||||
if (state.running && state.current_strategy) {
|
||||
currentStratEl.innerText = `Testing: [${state.current_strategy.name}] -> ${state.current_strategy.args}`;
|
||||
currentStratEl.innerText = `${_('Testing:')} [${state.current_strategy.name}] -> ${state.current_strategy.args}`;
|
||||
} else {
|
||||
currentStratEl.innerText = '';
|
||||
}
|
||||
@@ -1740,12 +1740,40 @@ export function renderStrategyFuzzerModal(ruleNames: string[] = []) {
|
||||
};
|
||||
|
||||
const typeLabels: Record<string, string> = {
|
||||
rst: 'TCP Reset Injection',
|
||||
throttle: 'Throttling / Deep Inspection',
|
||||
dns_block: 'DNS Blocking',
|
||||
ip_block: _('Блокировка по IP (Таймаут TCP SYN)'),
|
||||
unknown: 'Unknown DPI Pattern',
|
||||
none: 'No Blocking Detected',
|
||||
rst: _('TCP Reset Injection'),
|
||||
throttle: _('Throttling / Deep Inspection'),
|
||||
dns_block: _('DNS Blocking'),
|
||||
ip_block: _('IP Block (TCP SYN Timeout)'),
|
||||
unknown: _('Unknown DPI Pattern'),
|
||||
none: _('No Blocking Detected'),
|
||||
};
|
||||
|
||||
const getLocalizedDpiDetails = (
|
||||
det: Tachyon.FuzzerDpiDetection | null | undefined,
|
||||
) => {
|
||||
if (!det) return '';
|
||||
switch (det.type) {
|
||||
case 'ip_block':
|
||||
return _(
|
||||
'TCP connect timed out before TLS handshake — host is blocked at the IP layer. DPI bypass cannot unblock this; route via Sing-box VPN/Proxy outbound instead.',
|
||||
);
|
||||
case 'rst':
|
||||
return _(
|
||||
'TCP RST received from DPI — active TCP reset injection detected.',
|
||||
);
|
||||
case 'dns_block':
|
||||
return _(
|
||||
'DNS resolution failed — likely DNS-level blocking or hijacking.',
|
||||
);
|
||||
case 'throttle':
|
||||
return _(
|
||||
'DPI bandwidth throttling or delay detected — connection throttled during data transfer.',
|
||||
);
|
||||
case 'none':
|
||||
return _('Target accessible — no DPI blocking detected.');
|
||||
default:
|
||||
return det.details || _('Analysis inconclusive.');
|
||||
}
|
||||
};
|
||||
|
||||
const meta = typeMeta[detection.type] || typeMeta.unknown;
|
||||
@@ -1754,7 +1782,7 @@ export function renderStrategyFuzzerModal(ruleNames: string[] = []) {
|
||||
const ipBlockNotice =
|
||||
detection.type === 'ip_block'
|
||||
? `<div class="alert-message danger" style="margin-top: 8px;">
|
||||
⚠️ ${_('Обнаружена блокировка по IP! Ресурс блокируется на сетевом уровне (нет ответа на TCP SYN). Методы обхода DPI (Zapret / ByeDPI) бессильны для этого адреса — настройте маршрутизацию через прокси/VPN (Sing-box) для данного домена!')}
|
||||
⚠️ ${_('IP-level blocking detected! The resource is blocked at the network level (no TCP SYN response). DPI bypass methods (Zapret / ByeDPI) cannot bypass this address — configure proxy/VPN routing (Sing-box) for this domain!')}
|
||||
</div>`
|
||||
: '';
|
||||
|
||||
@@ -1768,7 +1796,7 @@ export function renderStrategyFuzzerModal(ruleNames: string[] = []) {
|
||||
</div>
|
||||
${detection.recommended_engines.length > 0 ? `<div style="font-size: 11px; opacity: 0.8;">${_('Recommended')}: ${detection.recommended_engines.join(', ')}</div>` : ''}
|
||||
</div>
|
||||
<div style="margin-top: 4px; opacity: 0.9; font-size: 11px;">${detection.details}</div>
|
||||
<div style="margin-top: 4px; opacity: 0.9; font-size: 11px;">${getLocalizedDpiDetails(detection)}</div>
|
||||
${ipBlockNotice}
|
||||
`;
|
||||
};
|
||||
|
||||
@@ -15,6 +15,7 @@ export default defineConfig({
|
||||
},
|
||||
esbuildOptions(options) {
|
||||
options.legalComments = 'none';
|
||||
options.charset = 'utf8';
|
||||
},
|
||||
onSuccess: () => {
|
||||
const outDir =
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1081,7 +1081,8 @@ function createParentalContent(section) {
|
||||
),
|
||||
);
|
||||
o.modalonly = true;
|
||||
o.default = "all";
|
||||
o.default = "domains";
|
||||
o.value("domains", _("Blocked Sites (Only block domains specified below)"));
|
||||
o.value("all", _("All Internet (Complete internet cutoff)"));
|
||||
o.value("sections", _("Specific Sections (Select sections below)"));
|
||||
|
||||
|
||||
@@ -433,58 +433,7 @@ const EntryPoint = {
|
||||
return form.Map.prototype.load.call(self);
|
||||
});
|
||||
};
|
||||
tachyonMap.handleSaveApply = function (ev, mode) {
|
||||
const refreshUiState = function () {
|
||||
main.TachyonShellMethods.getUiState()
|
||||
.then((response) => {
|
||||
if (
|
||||
response?.success &&
|
||||
typeof main.applyUiStateToStore === "function"
|
||||
) {
|
||||
main.applyUiStateToStore(response.data);
|
||||
}
|
||||
})
|
||||
.catch(() => null);
|
||||
};
|
||||
|
||||
if (main.store && typeof main.store.set === "function") {
|
||||
const servicesInfoWidget = main.store.get().servicesInfoWidget;
|
||||
main.store.set({
|
||||
servicesInfoWidget: {
|
||||
...servicesInfoWidget,
|
||||
data: {
|
||||
...servicesInfoWidget.data,
|
||||
tachyonStatus: "reloading",
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return this.handleSave(ev)
|
||||
.then(() => ui.changes.apply(mode == "0"))
|
||||
.then((result) => {
|
||||
if (
|
||||
main.TachyonShellMethods &&
|
||||
typeof main.TachyonShellMethods.serviceActionStart === "function"
|
||||
) {
|
||||
return main.TachyonShellMethods.serviceActionStart("reload")
|
||||
.then(() => {
|
||||
window.setTimeout(refreshUiState, 500);
|
||||
return result;
|
||||
})
|
||||
.catch(() => {
|
||||
window.setTimeout(refreshUiState, 500);
|
||||
return result;
|
||||
});
|
||||
}
|
||||
window.setTimeout(refreshUiState, 500);
|
||||
return result;
|
||||
})
|
||||
.catch((error) => {
|
||||
refreshUiState();
|
||||
throw error;
|
||||
});
|
||||
};
|
||||
tachyonMap.handleSaveApply = EntryPoint.handleSaveApply;
|
||||
|
||||
const rawTabOrder = uci.get(UCI_PACKAGE, "settings", "tab_order");
|
||||
const savedOrder = Array.isArray(rawTabOrder)
|
||||
@@ -758,6 +707,66 @@ const EntryPoint = {
|
||||
|
||||
return rendered;
|
||||
},
|
||||
|
||||
handleSaveApply: function (ev, mode) {
|
||||
const refreshUiState = function () {
|
||||
if (
|
||||
main.TachyonShellMethods &&
|
||||
typeof main.TachyonShellMethods.getUiState === "function"
|
||||
) {
|
||||
main.TachyonShellMethods.getUiState()
|
||||
.then((response) => {
|
||||
if (
|
||||
response?.success &&
|
||||
typeof main.applyUiStateToStore === "function"
|
||||
) {
|
||||
main.applyUiStateToStore(response.data);
|
||||
}
|
||||
})
|
||||
.catch(() => null);
|
||||
}
|
||||
};
|
||||
|
||||
if (main.store && typeof main.store.set === "function") {
|
||||
const servicesInfoWidget = main.store.get()?.servicesInfoWidget;
|
||||
if (servicesInfoWidget) {
|
||||
main.store.set({
|
||||
servicesInfoWidget: {
|
||||
...servicesInfoWidget,
|
||||
data: {
|
||||
...servicesInfoWidget.data,
|
||||
tachyonStatus: "reloading",
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return this.handleSave(ev)
|
||||
.then(() => ui.changes.apply(mode == "0"))
|
||||
.then((result) => {
|
||||
if (
|
||||
main.TachyonShellMethods &&
|
||||
typeof main.TachyonShellMethods.serviceActionStart === "function"
|
||||
) {
|
||||
return main.TachyonShellMethods.serviceActionStart("reload")
|
||||
.then(() => {
|
||||
window.setTimeout(refreshUiState, 500);
|
||||
return result;
|
||||
})
|
||||
.catch(() => {
|
||||
window.setTimeout(refreshUiState, 500);
|
||||
return result;
|
||||
});
|
||||
}
|
||||
window.setTimeout(refreshUiState, 500);
|
||||
return result;
|
||||
})
|
||||
.catch((error) => {
|
||||
refreshUiState();
|
||||
throw error;
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
return view.extend(EntryPoint);
|
||||
|
||||
@@ -855,7 +855,7 @@ msgid "Cache file path cannot be empty"
|
||||
msgstr "Путь к файлу кэша не может быть пустым"
|
||||
|
||||
msgid "Camou"
|
||||
msgstr ""
|
||||
msgstr "Camou"
|
||||
|
||||
msgid "Cancel"
|
||||
msgstr "Отмена"
|
||||
@@ -870,7 +870,7 @@ msgid "Cannot save settings"
|
||||
msgstr "Не удалось сохранить настройки"
|
||||
|
||||
msgid "Captive"
|
||||
msgstr ""
|
||||
msgstr "Captive"
|
||||
|
||||
msgid "Cascade connection"
|
||||
msgstr "Каскадное подключение"
|
||||
@@ -993,7 +993,7 @@ msgid "Click to show"
|
||||
msgstr "Нажмите, чтобы показать"
|
||||
|
||||
msgid "Client"
|
||||
msgstr ""
|
||||
msgstr "Клиент"
|
||||
|
||||
msgid "Client Address"
|
||||
msgstr "Адрес клиента"
|
||||
@@ -1263,7 +1263,7 @@ msgid "Dedicated cgroup unavailable"
|
||||
msgstr "Выделенная cgroup недоступна"
|
||||
|
||||
msgid "Default"
|
||||
msgstr ""
|
||||
msgstr "По умолчанию"
|
||||
|
||||
msgid "Default (auto)"
|
||||
msgstr "По умолчанию (авто)"
|
||||
@@ -2130,7 +2130,7 @@ msgid "France (fr)"
|
||||
msgstr "Франция (fr)"
|
||||
|
||||
msgid "Freedom"
|
||||
msgstr ""
|
||||
msgstr "Freedom"
|
||||
|
||||
msgid "Fri"
|
||||
msgstr "Пт"
|
||||
@@ -2787,7 +2787,7 @@ msgid "Japan (jp)"
|
||||
msgstr "Япония (jp)"
|
||||
|
||||
msgid "Jitsi"
|
||||
msgstr ""
|
||||
msgstr "Jitsi"
|
||||
|
||||
msgid "JSON outbound"
|
||||
msgstr "JSON outbound"
|
||||
@@ -5649,10 +5649,10 @@ msgid "When switching to another level, test every server and select the fastest
|
||||
msgstr "При переключении на другой уровень тестировать каждый сервер и выбирать самый быстрый вместо первого рабочего."
|
||||
|
||||
msgid "WHEP"
|
||||
msgstr ""
|
||||
msgstr "WHEP"
|
||||
|
||||
msgid "WHIP"
|
||||
msgstr ""
|
||||
msgstr "WHIP"
|
||||
|
||||
msgid "Why Discord fails?"
|
||||
msgstr "Почему не работает Discord?"
|
||||
@@ -5670,7 +5670,7 @@ msgid "working strategies"
|
||||
msgstr "рабочих стратегий"
|
||||
|
||||
msgid "WRT"
|
||||
msgstr ""
|
||||
msgstr "WRT"
|
||||
|
||||
msgid "XHTTP mode"
|
||||
msgstr "Режим XHTTP"
|
||||
@@ -6505,3 +6505,75 @@ msgstr "Скачивание и обработка списков"
|
||||
|
||||
msgid "Applying rules and subnet lists"
|
||||
msgstr "Применение правил и списков подсетей"
|
||||
|
||||
msgid "+ add"
|
||||
msgstr "+ добавить"
|
||||
|
||||
msgid "⚠️ Server received fakes"
|
||||
msgstr "⚠️ Сервер получил фейки"
|
||||
|
||||
msgid "✓ 32KB Streamed"
|
||||
msgstr "✓ 32KB Прокачано"
|
||||
|
||||
msgid "✗ Throttled at 16KB"
|
||||
msgstr "✗ Задушено на 16KB"
|
||||
|
||||
msgid "Analysis inconclusive."
|
||||
msgstr "Анализ не дал однозначного результата."
|
||||
|
||||
msgid "Blocked Sites (Only block domains specified below)"
|
||||
msgstr "Заблокированные сайты (Блокировать только указанные домены)"
|
||||
|
||||
msgid "DNS Blocking"
|
||||
msgstr "Блокировка DNS"
|
||||
|
||||
msgid "DNS resolution failed — likely DNS-level blocking or hijacking."
|
||||
msgstr "Сбой разрешения DNS — вероятно, блокировка или перехват на уровне DNS."
|
||||
|
||||
msgid "DPI bandwidth throttling or delay detected — connection throttled during data transfer."
|
||||
msgstr "Обнаружено замедление DPI — соединение заблокировано или задушено при передаче данных."
|
||||
|
||||
msgid "endpoints OK"
|
||||
msgstr "эндпоинтов доступно"
|
||||
|
||||
msgid "IP Block (TCP SYN Timeout)"
|
||||
msgstr "Блокировка по IP (Таймаут TCP SYN)"
|
||||
|
||||
msgid "IP-level blocking detected! The resource is blocked at the network level (no TCP SYN response). DPI bypass methods (Zapret / ByeDPI) cannot bypass this address — configure proxy/VPN routing (Sing-box) for this domain!"
|
||||
msgstr "Обнаружена блокировка по IP! Ресурс блокируется на сетевом уровне (нет ответа на TCP SYN). Методы обхода DPI (Zapret / ByeDPI) бессильны для этого адреса — настройте маршрутизацию через прокси/VPN (Sing-box) для данного домена!"
|
||||
|
||||
msgid "No Blocking Detected"
|
||||
msgstr "Блокировка не обнаружена"
|
||||
|
||||
msgid "Target accessible — no DPI blocking detected."
|
||||
msgstr "Цель доступна — блокировок DPI не обнаружено."
|
||||
|
||||
msgid "TCP connect timed out before TLS handshake — host is blocked at the IP layer. DPI bypass cannot unblock this; route via Sing-box VPN/Proxy outbound instead."
|
||||
msgstr "Таймаут TCP-подключения до рукопожатия TLS — узел заблокирован на уровне IP. Методы обхода DPI не помогут; настройте маршрутизацию через прокси/VPN Sing-box."
|
||||
|
||||
msgid "TCP Reset Injection"
|
||||
msgstr "Внедрение пакетов TCP Reset (RST)"
|
||||
|
||||
msgid "TCP RST received from DPI — active TCP reset injection detected."
|
||||
msgstr "Получен TCP RST от ТСПУ/DPI — зафиксирована активная инъекция сброса соединения."
|
||||
|
||||
msgid "Testing:"
|
||||
msgstr "Тестирование:"
|
||||
|
||||
msgid "Throttling / Deep Inspection"
|
||||
msgstr "Замедление / Глубокий анализ пакетов"
|
||||
|
||||
msgid "Unknown DPI Pattern"
|
||||
msgstr "Неизвестный тип DPI"
|
||||
|
||||
msgid "Zapret v1"
|
||||
msgstr "Zapret v1"
|
||||
|
||||
msgid "Zapret v2"
|
||||
msgstr "Zapret v2"
|
||||
|
||||
msgid "Allow only: "
|
||||
msgstr "Разрешить только: "
|
||||
|
||||
msgid "Block: "
|
||||
msgstr "Блокировать: "
|
||||
|
||||
@@ -9240,3 +9240,75 @@ msgstr ""
|
||||
#: src/tachyon/tabs/diagnostic/checks/runZapret2Check.ts:115
|
||||
msgid "Zapret2 sing-box route rules are not configured"
|
||||
msgstr ""
|
||||
|
||||
msgid "+ add"
|
||||
msgstr ""
|
||||
|
||||
msgid "⚠️ Server received fakes"
|
||||
msgstr ""
|
||||
|
||||
msgid "✓ 32KB Streamed"
|
||||
msgstr ""
|
||||
|
||||
msgid "✗ Throttled at 16KB"
|
||||
msgstr ""
|
||||
|
||||
msgid "Analysis inconclusive."
|
||||
msgstr ""
|
||||
|
||||
msgid "Blocked Sites (Only block domains specified below)"
|
||||
msgstr ""
|
||||
|
||||
msgid "DNS Blocking"
|
||||
msgstr ""
|
||||
|
||||
msgid "DNS resolution failed — likely DNS-level blocking or hijacking."
|
||||
msgstr ""
|
||||
|
||||
msgid "DPI bandwidth throttling or delay detected — connection throttled during data transfer."
|
||||
msgstr ""
|
||||
|
||||
msgid "endpoints OK"
|
||||
msgstr ""
|
||||
|
||||
msgid "IP Block (TCP SYN Timeout)"
|
||||
msgstr ""
|
||||
|
||||
msgid "IP-level blocking detected! The resource is blocked at the network level (no TCP SYN response). DPI bypass methods (Zapret / ByeDPI) cannot bypass this address — configure proxy/VPN routing (Sing-box) for this domain!"
|
||||
msgstr ""
|
||||
|
||||
msgid "No Blocking Detected"
|
||||
msgstr ""
|
||||
|
||||
msgid "Target accessible — no DPI blocking detected."
|
||||
msgstr ""
|
||||
|
||||
msgid "TCP connect timed out before TLS handshake — host is blocked at the IP layer. DPI bypass cannot unblock this; route via Sing-box VPN/Proxy outbound instead."
|
||||
msgstr ""
|
||||
|
||||
msgid "TCP Reset Injection"
|
||||
msgstr ""
|
||||
|
||||
msgid "TCP RST received from DPI — active TCP reset injection detected."
|
||||
msgstr ""
|
||||
|
||||
msgid "Testing:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Throttling / Deep Inspection"
|
||||
msgstr ""
|
||||
|
||||
msgid "Unknown DPI Pattern"
|
||||
msgstr ""
|
||||
|
||||
msgid "Zapret v1"
|
||||
msgstr ""
|
||||
|
||||
msgid "Zapret v2"
|
||||
msgstr ""
|
||||
|
||||
msgid "Allow only: "
|
||||
msgstr ""
|
||||
|
||||
msgid "Block: "
|
||||
msgstr ""
|
||||
|
||||
@@ -34,6 +34,7 @@ start_service() {
|
||||
initd_ucode start-service "$1" "$$"
|
||||
TACHYON_LAST_START_STATUS="$?"
|
||||
trap - INT TERM
|
||||
[ "$TACHYON_LAST_START_STATUS" = "0" ] && sync_service_triggers
|
||||
return "$TACHYON_LAST_START_STATUS"
|
||||
}
|
||||
|
||||
|
||||
@@ -1875,7 +1875,7 @@ function validate_schedule(schedule, sections, profiles) {
|
||||
if (length(sec_names) == 0) {
|
||||
let single_sec = option(schedule, "sections", "");
|
||||
if (single_sec != "") sec_names = [ single_sec ];
|
||||
else if (target != "all" && target != "sections" && target != "") sec_names = [ target ];
|
||||
else if (target != "all" && target != "sections" && target != "domains" && target != "") sec_names = [ target ];
|
||||
}
|
||||
for (let sec_name in sec_names) {
|
||||
let found = false;
|
||||
|
||||
@@ -1055,7 +1055,8 @@ function nft_add_schedule_rules_from_schedules(schedules, sections, table, profi
|
||||
[ "meta", "hour", sprintf("\"%s\"-\"%s\"", interval[0], interval[1]) ] : null;
|
||||
let base_match = nft_schedule_rule_base_match(dev_str, is_mac, family, days_args, time_args);
|
||||
|
||||
if (target == "all" || (length(target_sec_names) == 0 && target != "sections")) {
|
||||
let has_sched_domains = length(list_option(schedule, "blocked_domains")) > 0 || option(schedule, "blocked_domains", "") != "";
|
||||
if ((target == "all" || (length(target_sec_names) == 0 && target != "sections" && target != "domains")) && !has_sched_domains && target != "domains") {
|
||||
let fwd_rule = [];
|
||||
append_array(fwd_rule, base_match);
|
||||
append_array(fwd_rule, [ "counter", verdict ]);
|
||||
@@ -1067,7 +1068,7 @@ function nft_add_schedule_rules_from_schedules(schedules, sections, table, profi
|
||||
append_array(ctrl_rule, [ "counter", verdict ]);
|
||||
if (!nft_add_rule(table, "parental_control", ctrl_rule))
|
||||
log_debug("nft_add_schedule_rules: failed to add parental_control rule for " + dev_str);
|
||||
} else {
|
||||
} else if (length(target_sec_names) > 0) {
|
||||
for (let sec_name in target_sec_names) {
|
||||
let target_section = section_by_name(sections, sec_name);
|
||||
if (!target_section) continue;
|
||||
|
||||
@@ -291,7 +291,10 @@ function plan_state_from_file(path) {
|
||||
zapret2_queue: as_string(state.zapret2_queue_signature),
|
||||
zapret2_runtime: as_string(state.zapret2_runtime_signature),
|
||||
byedpi_runtime: as_string(state.byedpi_runtime_signature),
|
||||
wdtt_runtime: as_string(state.wdtt_runtime_signature),
|
||||
olcrtc_runtime: as_string(state.olcrtc_runtime_signature),
|
||||
list: as_string(state.list_signature),
|
||||
hosts_list: as_string(state.hosts_list_signature),
|
||||
cron: as_string(state.cron_signature),
|
||||
urltest_sections_known: state.__has.urltest_enabled_sections === true,
|
||||
urltest_sections: as_string(state.urltest_enabled_sections),
|
||||
|
||||
@@ -287,6 +287,40 @@ parental_jump_line="$(grep -n "mangle jump parental_control" "$NFT_LOG" | cut -d
|
||||
if [ "$local_return_line" -ge "$parental_jump_line" ]; then
|
||||
fail "localv4 return (line $local_return_line) must precede jump parental_control (line $parental_jump_line) to protect router panel access"
|
||||
fi
|
||||
# ─── Domain-based schedule must NOT add global counter drop rules ────────────
|
||||
cat >"$WORK_DIR/domain_schedule_fixture.json" <<'JSON'
|
||||
{
|
||||
"schedule": [
|
||||
{
|
||||
".name": "domain_only_sched",
|
||||
"enabled": "1",
|
||||
"device_ip": "192.168.1.180",
|
||||
"target": "all",
|
||||
"blocked_domains": [ "tiktok.com", "roblox.com" ],
|
||||
"action": "block"
|
||||
},
|
||||
{
|
||||
".name": "target_domains_sched",
|
||||
"enabled": "1",
|
||||
"device_ip": "192.168.1.181",
|
||||
"target": "domains",
|
||||
"action": "block"
|
||||
}
|
||||
]
|
||||
}
|
||||
JSON
|
||||
|
||||
rm -f "$NFT_LOG"
|
||||
touch "$NFT_LOG"
|
||||
nft_ucode nft-add-schedule-rules-fixture "$WORK_DIR/domain_schedule_fixture.json" "tachyon"
|
||||
|
||||
if grep -Eq "parental_(forward|control).*192\.168\.1\.180.*counter.*drop" "$NFT_LOG"; then
|
||||
fail "Schedule with blocked_domains must NOT add global counter drop in parental_forward/parental_control"
|
||||
fi
|
||||
|
||||
if grep -Eq "parental_(forward|control).*192\.168\.1\.181.*counter.*drop" "$NFT_LOG"; then
|
||||
fail "Schedule with target=domains must NOT add global counter drop in parental_forward/parental_control"
|
||||
fi
|
||||
|
||||
printf 'Parental control, profiles and schedule tests passed\n'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user