fix: auto-switch DNS servers on protocol change in settings and per-rule

This commit is contained in:
Dushnilin
2026-07-31 20:05:33 +03:00
parent 6061c92571
commit 207f77954a
2 changed files with 56 additions and 10 deletions
@@ -455,6 +455,8 @@ const outboundNameChoicesInflight = new Map();
const outboundNameSourceOptions = new Map(); const outboundNameSourceOptions = new Map();
const sectionGroupSourceOptions = new Map(); const sectionGroupSourceOptions = new Map();
const dashboardFilterChoiceRefreshers = new Map(); const dashboardFilterChoiceRefreshers = new Map();
const perRuleDnsTypeState = new Map();
const perRuleDnsWidgets = new Map();
const SECTION_CACHE_DIR = "/var/run/tachyon/section-cache"; const SECTION_CACHE_DIR = "/var/run/tachyon/section-cache";
const COUNTRY_CODES = const COUNTRY_CODES =
"AD AE AF AG AI AL AM AO AQ AR AS AT AU AW AX AZ BA BB BD BE BF BG BH BI BJ BL BM BN BO BQ BR BS BT BV BW BY BZ CA CC CD CF CG CH CI CK CL CM CN CO CR CU CV CW CX CY CZ DE DJ DK DM DO DZ EC EE EG EH ER ES ET FI FJ FK FM FO FR GA GB GD GE GF GG GH GI GL GM GN GP GQ GR GS GT GU GW GY HK HM HN HR HT HU ID IE IL IM IN IO IQ IR IS IT JE JM JO JP KE KG KH KI KM KN KP KR KW KY KZ LA LB LC LI LK LR LS LT LU LV LY MA MC MD ME MF MG MH MK ML MM MN MO MP MQ MR MS MT MU MV MW MX MY MZ NA NC NE NF NG NI NL NO NP NR NU NZ OM PA PE PF PG PH PK PL PM PN PR PS PT PW PY QA RE RO RS RU RW SA SB SC SD SE SG SH SI SJ SK SL SM SN SO SR SS ST SV SX SY SZ TC TD TF TG TH TJ TK TL TM TN TO TR TT TV TW TZ UA UG UM US UY UZ VA VC VE VG VI VN VU WF WS YE YT ZA ZM ZW XK".split( "AD AE AF AG AI AL AM AO AQ AR AS AT AU AW AX AZ BA BB BD BE BF BG BH BI BJ BL BM BN BO BQ BR BS BT BV BW BY BZ CA CC CD CF CG CH CI CK CL CM CN CO CR CU CV CW CX CY CZ DE DJ DK DM DO DZ EC EE EG EH ER ES ET FI FJ FK FM FO FR GA GB GD GE GF GG GH GI GL GM GN GP GQ GR GS GT GU GW GY HK HM HN HR HT HU ID IE IL IM IN IO IQ IR IS IT JE JM JO JP KE KG KH KI KM KN KP KR KW KY KZ LA LB LC LI LK LR LS LT LU LV LY MA MC MD ME MF MG MH MK ML MM MN MO MP MQ MR MS MT MU MV MW MX MY MZ NA NC NE NF NG NI NL NO NP NR NU NZ OM PA PE PF PG PH PK PL PM PN PR PS PT PW PY QA RE RO RS RU RW SA SB SC SD SE SG SH SI SJ SK SL SM SN SO SR SS ST SV SX SY SZ TC TD TF TG TH TJ TK TL TM TN TO TR TT TV TW TZ UA UG UM US UY UZ VA VC VE VG VI VN VU WF WS YE YT ZA ZM ZW XK".split(
@@ -1527,6 +1529,7 @@ function configureLiveDynamicListChoices(option, getChoices) {
dashboardFilterChoiceRefreshers.set(section_id, new Set()); dashboardFilterChoiceRefreshers.set(section_id, new Set());
} }
dashboardFilterChoiceRefreshers.get(section_id).add(refreshChoices); dashboardFilterChoiceRefreshers.get(section_id).add(refreshChoices);
perRuleDnsWidgets.set(section_id, widget);
return node; return node;
}; };
@@ -7257,12 +7260,27 @@ function createSectionContent(section) {
o.depends("action", "dns"); o.depends("action", "dns");
o.modalonly = true; o.modalonly = true;
configureLiveDynamicListChoices(o, (section_id) => { configureLiveDynamicListChoices(o, (section_id) => {
const sel = document.getElementById("cbid.tachyon." + section_id + ".dns_type"); const dnsType = perRuleDnsTypeState.get(section_id) || "udp";
const dnsType = (sel ? sel.value : null) || "udp";
const servers = main.DNS_SERVERS_BY_PROTOCOL[dnsType] || main.DNS_SERVERS_BY_PROTOCOL.udp; const servers = main.DNS_SERVERS_BY_PROTOCOL[dnsType] || main.DNS_SERVERS_BY_PROTOCOL.udp;
return Object.entries(servers).map(([value, label]) => ({ value, label: _(label) })); return Object.entries(servers).map(([value, label]) => ({ value, label: _(label) }));
}); });
perRuleDnsTypeOption.onchange = function (_ev, section_id) { perRuleDnsTypeOption.onchange = function (_ev, section_id, value) {
const newType = value || "udp";
const oldType = perRuleDnsTypeState.get(section_id) || "udp";
perRuleDnsTypeState.set(section_id, newType);
if (newType !== oldType) {
const widget = perRuleDnsWidgets.get(section_id);
if (widget) {
const servers = main.DNS_SERVERS_BY_PROTOCOL[newType] || main.DNS_SERVERS_BY_PROTOCOL.udp;
const defaultLabels = {};
Object.entries(servers).forEach(([v, l]) => { defaultLabels[v] = _(l); });
const defaultServers = Object.keys(servers).slice(0, 1);
widget.choices = defaultLabels;
widget.setValue(defaultServers);
}
}
const refreshers = dashboardFilterChoiceRefreshers.get(section_id); const refreshers = dashboardFilterChoiceRefreshers.get(section_id);
if (refreshers) { if (refreshers) {
refreshers.forEach((fn) => fn()); refreshers.forEach((fn) => fn());
@@ -215,15 +215,28 @@ function configureDnsDynamicList(option, getChoices, defaultValue) {
}; };
node.addEventListener("mousedown", refreshBeforeOpening, true); node.addEventListener("mousedown", refreshBeforeOpening, true);
node.addEventListener("focusin", refreshBeforeOpening, true); node.addEventListener("focusin", refreshBeforeOpening, true);
if (!settingsDnsDynamicRefreshers.has(section_id)) { if (!settingsDnsDynamicState.refreshers.has(section_id)) {
settingsDnsDynamicRefreshers.set(section_id, new Set()); settingsDnsDynamicState.refreshers.set(section_id, new Set());
} }
settingsDnsDynamicRefreshers.get(section_id).add(refreshChoices); settingsDnsDynamicState.refreshers.get(section_id).add(refreshChoices);
settingsDnsDynamicState.widget = widget;
settingsDnsDynamicState.option = this;
return node; return node;
}; };
} }
const settingsDnsDynamicRefreshers = new Map(); const settingsDnsDynamicState = {
dnsType: null,
widget: null,
option: null,
refreshers: new Map(),
};
function getDefaultDnsServers(dnsType) {
const servers = main.DNS_SERVERS_BY_PROTOCOL[dnsType] || main.DNS_SERVERS_BY_PROTOCOL.udp;
const keys = Object.keys(servers);
return keys.length > 0 ? [keys[0]] : ["77.88.8.8"];
}
function configureDnsDuration( function configureDnsDuration(
option, option,
@@ -928,6 +941,8 @@ function showImportHostsModal(section_id, optionRef) {
} }
function createSettingsContent(section, capabilities) { function createSettingsContent(section, capabilities) {
settingsDnsDynamicState.dnsType = uci.get(UCI_PACKAGE, "settings", "dns_type") || "udp";
let o = section.option( let o = section.option(
form.ListValue, form.ListValue,
"dns_type", "dns_type",
@@ -952,8 +967,7 @@ function createSettingsContent(section, capabilities) {
), ),
); );
configureDnsDynamicList(dnsOption, (_section_id) => { configureDnsDynamicList(dnsOption, (_section_id) => {
const sel = document.getElementById("cbid.tachyon.settings.dns_type"); const dnsType = settingsDnsDynamicState.dnsType || "udp";
const dnsType = (sel ? sel.value : null) || "udp";
return getDnsServerChoices(dnsType); return getDnsServerChoices(dnsType);
}, "77.88.8.8"); }, "77.88.8.8");
@@ -972,7 +986,21 @@ function createSettingsContent(section, capabilities) {
); );
dnsTypeOption.onchange = function (_ev, section_id, value) { dnsTypeOption.onchange = function (_ev, section_id, value) {
const refreshers = settingsDnsDynamicRefreshers.get(section_id); const newType = value || "udp";
if (newType === settingsDnsDynamicState.dnsType) return;
settingsDnsDynamicState.dnsType = newType;
const widget = settingsDnsDynamicState.widget;
if (widget) {
const servers = main.DNS_SERVERS_BY_PROTOCOL[newType] || main.DNS_SERVERS_BY_PROTOCOL.udp;
const defaultLabels = {};
Object.entries(servers).forEach(([v, l]) => { defaultLabels[v] = _(l); });
const defaultServers = getDefaultDnsServers(newType);
widget.choices = defaultLabels;
widget.setValue(defaultServers);
}
const refreshers = settingsDnsDynamicState.refreshers.get(section_id);
if (refreshers) { if (refreshers) {
refreshers.forEach((fn) => fn()); refreshers.forEach((fn) => fn());
} }