⛅ Sync 2026-09-29 21:45:00

This commit is contained in:
github-actions[bot] committed 2026-09-29 21:45:00 +08:00
1 parent a4d6e3e4b9
commit da77daf88e
191 files changed
+8077 -6247

No files matched your search

@@ -303,6 +303,11 @@ return view.extend({
o.depends('routing_mode', 'bypass_mainland_china');
o.rmempty = false;
o = s.taboption('routing', form.Flag, 'block_https_rr', _('Block HTTPS/SVCB DNS records'),
_('Answer HTTPS (type 65) and SVCB (type 64) queries with an empty response. Keeps clients off HTTPS-RR/ECH, which this DNS chain cannot serve through some proxies; disable it if ECH is wanted.'));
o.default = o.enabled;
o.rmempty = false;
o = s.taboption('routing', form.ListValue, 'tun_dns_mode', _('TUN DNS mode (1.14)'),
_('Since sing-box 1.14 the default (Unset) behaves as hijack: sing-box sets the platform interface DNS and hijacks port 53. On OpenWrt this overlaps with the own dnsmasq/nftables DNS hijack of this plugin, so keep Disabled on a gateway unless you need sing-box to own TUN DNS.'));
o.value('default', _('Unset (default)'));
@@ -1064,7 +1069,7 @@ return view.extend({
so.modalonly = true;
so = ss.option(form.DynamicList, 'headers', _('Headers'),
_('Additional headers to be sent to the DNS server.'));
_('Additional headers to be sent to the DNS server, one <code>Name: value</code> per line.'));
so.depends('type', 'https');
so.depends('type', 'h3');
so.modalonly = true;
@@ -184,6 +184,11 @@ function parseShareLink(uri, features) {
if (url.search && url.searchParams.get('plugin')) {
let plugin_info = url.searchParams.get('plugin').split(';');
plugin = plugin_info[0];
/* sing-box only knows obfs-local; simple-obfs (an old
alias providers still emit) would otherwise be rejected
as "plugin not found" and take the whole config with it */
if (plugin === 'simple-obfs')
plugin = 'obfs-local';
plugin_opts = (plugin_info.length > 1) ? plugin_info.slice(1).join(';') : null;
}
@@ -302,7 +307,10 @@ function parseShareLink(uri, features) {
tls_reality_public_key: params.get('pbk') ? decodeURIComponent(params.get('pbk')) : null,
tls_reality_short_id: params.get('sid'),
tls_utls: features.with_utls ? params.get('fp') : null,
vless_flow: ['tls', 'reality'].includes(params.get('security')) ? params.get('flow') : null
/* only the value sing-box supports: any other flow is
rejected with "unsupported flow" and one bad node breaks
the whole generated config */
vless_flow: (['tls', 'reality'].includes(params.get('security')) && params.get('flow') === 'xtls-rprx-vision') ? params.get('flow') : null
};
switch (params.get('type')) {
case 'grpc':
@@ -332,8 +340,10 @@ function parseShareLink(uri, features) {
break;
case 'vmess':
/* "Lovely" shadowrocket format */
if (uri.includes('&'))
/* "Lovely" shadowrocket format; uri is the split scheme/rest
array, so this has to test the link body (testing the array
itself compared '&' against its elements and never matched) */
if (uri[1].includes('&'))
return null;
/* https://github.com/2dust/v2rayN/wiki/Description-of-VMess-share-link */
@@ -1149,7 +1159,15 @@ return view.extend({
let packet_encoding = uci.get(data[0], 'subscription', 'packet_encoding');
let imported_node = 0;
input_links.forEach((l) => {
let config = parseShareLink(l, features);
let config;
try {
config = parseShareLink(l, features);
} catch (e) {
/* a single unparsable link must not abort
the whole import (the changes made so
far were left unsaved before) */
config = null;
}
if (config) {
if (config.tls === '1' && allow_insecure === '1')
config.tls_insecure = '1'
@@ -1157,7 +1175,16 @@ return view.extend({
config.packet_encoding = packet_encoding
let nameHash = hp.calcStringMD5(config.label);
let previous = uci.get(data[0], nameHash) || {};
let sid = uci.add(data[0], 'node', nameHash);
/* drop options the node no longer has:
uci.set() only writes the keys below,
so re-importing a changed protocol
used to leave the old fields behind */
Object.keys(previous).forEach((k) => {
if (k.charAt(0) !== '.' && !(k in config))
uci.unset(data[0], sid, k);
});
Object.keys(config).forEach((k) => {
uci.set(data[0], sid, k, config[k]);
});
@@ -257,6 +257,15 @@ return view.extend({
o.cfgvalue = L.bind(getResVersion, this, o, 'gfw_list');
o.rawhtml = true;
/* local rule-sets (used by bypass_mainland_china when present) */
o = s.option(form.DummyValue, '_geoip_cn_version', _('GeoIP CN rule-set version'));
o.cfgvalue = L.bind(getResVersion, this, o, 'geoip_cn');
o.rawhtml = true;
o = s.option(form.DummyValue, '_geosite_cn_version', _('GeoSite CN rule-set version'));
o.cfgvalue = L.bind(getResVersion, this, o, 'geosite_cn');
o.rawhtml = true;
o = s.option(form.Value, 'github_token', _('GitHub token'));
o.password = true;
o.renderWidget = function() {