🚀 Sync 2026-03-20 14:18:42

This commit is contained in:
github-actions[bot] committed 2026-03-20 14:18:42 +08:00
1 parent 3f5e547363
commit 72b1d9508b
81 files changed
+2797 -975

No files matched your search

+3 -3
View File
@@ -1,12 +1,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-mosdns
PKG_VERSION:=1.6.17
PKG_RELEASE:=1
PKG_VERSION:=1.7.0
PKG_RELEASE:=2
LUCI_TITLE:=LuCI Support for mosdns
LUCI_PKGARCH:=all
LUCI_DEPENDS:=+mosdns +jsonfilter +curl +v2ray-geoip +v2ray-geosite +v2dat
LUCI_DEPENDS:=+mosdns +curl +v2ray-geoip +v2ray-geosite +v2dat
PKG_MAINTAINER:=sbwml <admin@cooluc.com>
@@ -70,31 +70,42 @@ async function loadCodeMirrorResources() {
await loadScripts();
}
var callMosdns = rpc.declare({
object: 'luci.mosdns',
method: 'get_version',
expect: { '': {} }
});
var callFlushCache = rpc.declare({
object: 'luci.mosdns',
method: 'flush_cache',
expect: { '': {} }
});
return view.extend({
load: function () {
return Promise.all([
L.resolveDefault(fs.exec('/usr/bin/mosdns', ['version']), null),
L.resolveDefault(callMosdns(), null),
]);
},
handleFlushCache: function (m, section_id, ev) {
return fs.exec('/usr/share/mosdns/mosdns.sh', ['flush'])
.then(function (lazy_cache) {
var res = lazy_cache.code;
if (res === 0) {
ui.addNotification(null, E('p', _('Flushing DNS Cache Success.')), 'info');
} else {
ui.addNotification(null, E('p', _('Flushing DNS Cache Failed, Please check if MosDNS is running.')), 'error');
}
});
handleFlushCache: function () {
return callFlushCache().then(function(res) {
if (res.success) {
ui.addNotification(null, E('p', _('Flushing DNS Cache Success.')), 'info');
} else {
ui.addNotification(null, E('p', _('Flushing DNS Cache Failed, Please check if MosDNS is running.') + (res.error ? ': ' + res.error : '')), 'error');
}
});
},
render: function (basic) {
render: function (data) {
var m, s, o, v;
v = '';
if (basic[0] && basic[0].code === 0) {
v = basic[0].stdout.trim();
var version = (data[0] && data[0].version) ? data[0].version : null;
if (version) {
v = version;
}
m = new form.Map('mosdns', _('MosDNS') + '&#160;' + v,
_('MosDNS is a plugin-based DNS forwarder/traffic splitter.'));
@@ -147,6 +158,7 @@ return view.extend({
o.depends('configfile', '/var/etc/mosdns.json');
o = s.taboption('basic', form.Value, 'listen_address', _('Listen Address'));
o.default = '0.0.0.0';
o.depends('configfile', '/var/etc/mosdns.json');
o = s.taboption('basic', form.ListValue, 'log_level', _('Log Level'));
@@ -389,7 +401,7 @@ return view.extend({
/* api */
o = s.taboption('api', form.Value, 'listen_port_api', _('API Listen port'));
o.datatype = 'and(port,min(1))';
o.default = 9091;
o.default = 52001;
o.depends('configfile', '/var/etc/mosdns.json');
o = s.taboption('api', form.Button, '_flush_cache', null,
@@ -397,7 +409,7 @@ return view.extend({
o.title = '&#160;';
o.inputtitle = _('Flush DNS Cache');
o.inputstyle = 'apply';
o.onclick = L.bind(this.handleFlushCache, this, m);
o.onclick = L.bind(this.handleFlushCache, this);
o.depends('cache', '1');
/* configuration */
@@ -3,18 +3,28 @@
'require fs';
'require poll';
'require view';
'require rpc';
'require ui';
var callPrintLog = rpc.declare({
object: 'luci.mosdns',
method: 'print_log',
expect: { '': {} }
});
var callCleanLog = rpc.declare({
object: 'luci.mosdns',
method: 'clean_log',
expect: { '': {} }
});
var scrollPosition = 0;
var userScrolled = false;
var logTextarea;
function pollLog() {
return Promise.all([
fs.exec_direct('/usr/share/mosdns/mosdns.sh', ['printlog']).then(function (res) {
return res.trim().split(/\n/).join('\n');
}),
]).then(function (data) {
logTextarea.value = data[0] || _('No log data.');
return callPrintLog().then(function (res) {
logTextarea.value = res.log || _('No log data.');
if (!userScrolled) {
logTextarea.scrollTop = logTextarea.scrollHeight;
@@ -26,8 +36,13 @@ function pollLog() {
return view.extend({
handleCleanLogs: function () {
return fs.exec('/usr/share/mosdns/mosdns.sh', ['cleanlog'])
.catch(function (e) { ui.addNotification(null, E('p', e.message)) });
return callCleanLog().then(function(res) {
if (res.success) {
logTextarea.value = ''; // Clear textarea on success
} else {
ui.addNotification(null, E('p', _('Failed to clean logs.') + (res.error ? ': ' + res.error : '')), 'error');
}
}).catch(function (e) { ui.addNotification(null, E('p', e.message)) });
},
render: function () {
@@ -3,6 +3,12 @@
'require fs';
'require ui';
'require view';
'require rpc';
var callRestart = rpc.declare({
object: 'luci.mosdns',
method: 'restart'
});
return view.extend({
render: function () {
@@ -24,6 +30,7 @@ return view.extend({
s.tab('localptrlist', _('Block PTR'));
s.tab('streamingmedialist', _('Streaming Media'));
// --- White Lists ---
o = s.taboption('whitelist', form.TextValue, '_whitelist',
null,
'<font color=\'red\'>'
@@ -41,13 +48,19 @@ return view.extend({
if (value == formvalue) {
return;
}
return fs.write('/etc/mosdns/rule/whitelist.txt', formvalue.trim().replace(/\r\n/g, '\n') + '\n')
return fs.write('/etc/mosdns/rule/whitelist.txt', (formvalue.trim() ? formvalue.trim().replace(/\r\n/g, '\n') + '\n' : ''))
.catch(function (e) {
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
});
});
};
o.remove = function (section_id) {
return fs.write('/etc/mosdns/rule/whitelist.txt', '').catch(function (e) {
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
});
};
// --- Block Lists ---
o = s.taboption('blocklist', form.TextValue, '_blocklist',
null,
'<font color=\'red\'>'
@@ -65,13 +78,19 @@ return view.extend({
if (value == formvalue) {
return;
}
return fs.write('/etc/mosdns/rule/blocklist.txt', formvalue.trim().replace(/\r\n/g, '\n') + '\n')
return fs.write('/etc/mosdns/rule/blocklist.txt', (formvalue.trim() ? formvalue.trim().replace(/\r\n/g, '\n') + '\n' : ''))
.catch(function (e) {
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
});
});
};
o.remove = function (section_id) {
return fs.write('/etc/mosdns/rule/blocklist.txt', '').catch(function (e) {
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
});
};
// --- Grey Lists ---
o = s.taboption('greylist', form.TextValue, '_greylist',
null,
'<font color=\'red\'>'
@@ -89,13 +108,19 @@ return view.extend({
if (value == formvalue) {
return;
}
return fs.write('/etc/mosdns/rule/greylist.txt', formvalue.trim().replace(/\r\n/g, '\n') + '\n')
return fs.write('/etc/mosdns/rule/greylist.txt', (formvalue.trim() ? formvalue.trim().replace(/\r\n/g, '\n') + '\n' : ''))
.catch(function (e) {
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
});
});
};
o.remove = function (section_id) {
return fs.write('/etc/mosdns/rule/greylist.txt', '').catch(function (e) {
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
});
};
// --- DDNS Lists ---
o = s.taboption('ddnslist', form.TextValue, '_ddnslist',
null,
'<font color=\'red\'>'
@@ -113,13 +138,19 @@ return view.extend({
if (value == formvalue) {
return;
}
return fs.write('/etc/mosdns/rule/ddnslist.txt', formvalue.trim().replace(/\r\n/g, '\n') + '\n')
return fs.write('/etc/mosdns/rule/ddnslist.txt', (formvalue.trim() ? formvalue.trim().replace(/\r\n/g, '\n') + '\n' : ''))
.catch(function (e) {
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
});
});
};
o.remove = function (section_id) {
return fs.write('/etc/mosdns/rule/ddnslist.txt', '').catch(function (e) {
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
});
};
// --- Hosts ---
o = s.taboption('hostslist', form.TextValue, '_hostslist',
null,
'<font color=\'red\'>'
@@ -137,13 +168,19 @@ return view.extend({
if (value == formvalue) {
return;
}
return fs.write('/etc/mosdns/rule/hosts.txt', formvalue.trim().replace(/\r\n/g, '\n') + '\n')
return fs.write('/etc/mosdns/rule/hosts.txt', (formvalue.trim() ? formvalue.trim().replace(/\r\n/g, '\n') + '\n' : ''))
.catch(function (e) {
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
});
});
};
o.remove = function (section_id) {
return fs.write('/etc/mosdns/rule/hosts.txt', '').catch(function (e) {
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
});
};
// --- Redirect ---
o = s.taboption('redirectlist', form.TextValue, '_redirectlist',
null,
'<font color=\'red\'>'
@@ -161,13 +198,19 @@ return view.extend({
if (value == formvalue) {
return;
}
return fs.write('/etc/mosdns/rule/redirect.txt', formvalue.trim().replace(/\r\n/g, '\n') + '\n')
return fs.write('/etc/mosdns/rule/redirect.txt', (formvalue.trim() ? formvalue.trim().replace(/\r\n/g, '\n') + '\n' : ''))
.catch(function (e) {
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
});
});
};
o.remove = function (section_id) {
return fs.write('/etc/mosdns/rule/redirect.txt', '').catch(function (e) {
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
});
};
// --- Block PTR ---
o = s.taboption('localptrlist', form.TextValue, '_localptrlist',
null,
'<font color=\'red\'>'
@@ -185,13 +228,19 @@ return view.extend({
if (value == formvalue) {
return;
}
return fs.write('/etc/mosdns/rule/local-ptr.txt', formvalue.trim().replace(/\r\n/g, '\n') + '\n')
return fs.write('/etc/mosdns/rule/local-ptr.txt', (formvalue.trim() ? formvalue.trim().replace(/\r\n/g, '\n') + '\n' : ''))
.catch(function (e) {
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
});
});
};
o.remove = function (section_id) {
return fs.write('/etc/mosdns/rule/local-ptr.txt', '').catch(function (e) {
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
});
};
// --- Streaming Media ---
o = s.taboption('streamingmedialist', form.TextValue, '_streamingmedialist',
null,
'<font color=\'red\'>'
@@ -209,12 +258,17 @@ return view.extend({
if (value == formvalue) {
return;
}
return fs.write('/etc/mosdns/rule/streaming.txt', formvalue.trim().replace(/\r\n/g, '\n') + '\n')
return fs.write('/etc/mosdns/rule/streaming.txt', (formvalue.trim() ? formvalue.trim().replace(/\r\n/g, '\n') + '\n' : ''))
.catch(function (e) {
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
});
});
};
o.remove = function (section_id) {
return fs.write('/etc/mosdns/rule/streaming.txt', '').catch(function (e) {
ui.addNotification(null, E('p', _('Unable to save contents: %s').format(e.message)));
});
};
return m.render();
},
@@ -222,9 +276,13 @@ return view.extend({
handleSaveApply: function (ev) {
var m = this.map;
onclick = L.bind(this.handleSave, this, m);
return fs.exec('/etc/init.d/mosdns', ['restart'])
.then(function () {
window.location.reload();
return callRestart()
.then(function (res) {
if (res && res.code === 0) {
window.location.reload();
} else {
ui.addNotification(null, E('p', _('Failed to restart mosdns: %s').format(res.output || 'Unknown error')));
}
})
.catch(function (e) {
ui.addNotification(null, E('p', _('Failed to restart mosdns: %s').format(e.message)));
@@ -5,16 +5,22 @@
'require view';
return view.extend({
handleUpdate: function (m, section_id, ev) {
return fs.exec('/usr/share/mosdns/mosdns.sh', ['geodata'])
.then(function (i) {
var res = i.code;
if (res === 0) {
handleUpdate: function () {
ui.showModal(_('Updating...'), [
E('p', { 'class': 'spinning' }, _('Please wait, this may take a few moments...')),
]);
return fs.exec('/usr/share/mosdns/mosdns.uc', ['update'])
.then(function (res) {
ui.hideModal();
if (res.code === 0) {
ui.addNotification(null, E('p', _('Update success')), 'info');
} else {
ui.addNotification(null, E('p', i.stderr + '<br />' + i.stdout), 'warn');
ui.addNotification(null, E('p', res.stderr + '<br />' + res.stdout), 'warn');
ui.addNotification(null, E('p', _('Update failed, Please check the network status')), 'error');
}
}).catch(function (e) {
ui.hideModal();
ui.addNotification(null, E('p', _('Update failed: %s').format(e.message)), 'error');
});
},
@@ -68,7 +74,7 @@ return view.extend({
o.title = _('Database Update');
o.inputtitle = _('Check And Update');
o.inputstyle = 'apply';
o.onclick = L.bind(this.handleUpdate, this, m);
o.onclick = L.bind(this.handleUpdate, this);
return m.render();
}
+794
View File
@@ -0,0 +1,794 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-03-20 09:23+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: htdocs/luci-static/resources/view/mosdns/basic.js:31
#: htdocs/luci-static/resources/view/mosdns/basic.js:33
#: htdocs/luci-static/resources/view/mosdns/basic.js:110
#: htdocs/luci-static/resources/view/mosdns/logs.js:70
msgid "MosDNS"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:31
msgid "RUNNING"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:33
msgid "NOT RUNNING"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:95
msgid "Flushing DNS Cache Success."
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:97
msgid "Flushing DNS Cache Failed, Please check if MosDNS is running."
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:111
msgid "MosDNS is a plugin-based DNS forwarder/traffic splitter."
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:133
msgid "Collecting data..."
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:139
msgid "Basic Options"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:140
msgid "Advanced Options"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:141
msgid "Cloudflare Options"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:142
msgid "API Options"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:143
msgid "GeoData Export"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:146
#: htdocs/luci-static/resources/view/mosdns/basic.js:370
msgid "Enabled"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:150
msgid "Config File"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:151
msgid "Default Config"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:152
msgid "Custom Config"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:155
msgid "Listen Port"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:160
msgid "Listen Address"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:164
msgid "Log Level"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:165
msgid "Debug"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:166
msgid "Info"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:167
msgid "Warning"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:168
msgid "Error"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:172
msgid "Log File"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:177
msgid "DNS Forward"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:177
msgid "Forward Dnsmasq Domain Name resolution requests to MosDNS"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:181
msgid "DNS redirect"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:181
msgid "Force redirect all local DNS queries to MosDNS, a.k.a. DNS Hijacking"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:186
msgid "China DNS prefer IPv4"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:187
msgid ""
"IPv4 is preferred for China DNS resolution of dual-stack addresses, and is "
"not affected when the destination is IPv6 only"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:191
msgid "Remote DNS prefer IPv4"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:192
msgid ""
"IPv4 is preferred for Remote / Streaming Media DNS resolution of dual-stack "
"addresses, and is not affected when the destination is IPv6 only"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:196
msgid "Custom China DNS"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:196
msgid "Follow WAN interface DNS if not enabled"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:200
msgid "Apple domains optimization"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:201
msgid ""
"For Apple domains equipped with Chinese mainland CDN, always responsive to "
"Chinese CDN IP addresses"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:205
msgid "China DNS server"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:206
#: htdocs/luci-static/resources/view/mosdns/basic.js:254
msgid "Tencent Public DNS (119.29.29.29)"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:207
#: htdocs/luci-static/resources/view/mosdns/basic.js:255
msgid "Tencent Public DNS (119.28.28.28)"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:208
#: htdocs/luci-static/resources/view/mosdns/basic.js:256
msgid "Aliyun Public DNS (223.5.5.5)"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:209
#: htdocs/luci-static/resources/view/mosdns/basic.js:257
msgid "Aliyun Public DNS (223.6.6.6)"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:210
msgid "TrafficRoute Public DNS (180.184.1.1)"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:211
msgid "TrafficRoute Public DNS (180.184.2.2)"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:212
#: htdocs/luci-static/resources/view/mosdns/basic.js:258
msgid "Xinfeng Public DNS (114.114.114.114)"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:213
#: htdocs/luci-static/resources/view/mosdns/basic.js:259
msgid "Xinfeng Public DNS (114.114.115.115)"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:214
#: htdocs/luci-static/resources/view/mosdns/basic.js:260
msgid "Baidu Public DNS (180.76.76.76)"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:215
msgid "Tencent Public DNS (DNS over HTTPS)"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:216
msgid "Aliyun Public DNS (DNS over QUIC)"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:217
msgid "Aliyun Public DNS (DNS over HTTPS)"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:218
msgid "Aliyun Public DNS (DNS over HTTP/3)"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:219
msgid "360 Public DNS (DNS over HTTPS)"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:223
msgid "Remote DNS server"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:224
#: htdocs/luci-static/resources/view/mosdns/basic.js:241
#: htdocs/luci-static/resources/view/mosdns/basic.js:262
msgid "CloudFlare Public DNS (1.1.1.1)"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:225
#: htdocs/luci-static/resources/view/mosdns/basic.js:242
msgid "CloudFlare Public DNS (1.0.0.1)"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:226
#: htdocs/luci-static/resources/view/mosdns/basic.js:243
#: htdocs/luci-static/resources/view/mosdns/basic.js:261
msgid "Google Public DNS (8.8.8.8)"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:227
#: htdocs/luci-static/resources/view/mosdns/basic.js:244
msgid "Google Public DNS (8.8.4.4)"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:228
#: htdocs/luci-static/resources/view/mosdns/basic.js:245
msgid "Quad9 Public DNS (9.9.9.9)"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:229
#: htdocs/luci-static/resources/view/mosdns/basic.js:246
msgid "Quad9 Public DNS (149.112.112.112)"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:230
#: htdocs/luci-static/resources/view/mosdns/basic.js:247
msgid "Cisco Public DNS (208.67.222.222)"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:231
#: htdocs/luci-static/resources/view/mosdns/basic.js:248
msgid "Cisco Public DNS (208.67.220.220)"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:235
msgid "Custom Stream Media DNS"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:236
msgid "Netflix, Disney+, Hulu and streaming media rules list will use this DNS"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:240
msgid "Streaming Media DNS server"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:252
msgid "Bootstrap DNS servers"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:253
msgid ""
"Bootstrap DNS servers are used to resolve IP addresses of the DoH/DoT "
"resolvers you specify as upstreams"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:267
msgid "Concurrent"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:268
msgid ""
"DNS query request concurrency, The number of upstream DNS servers that are "
"allowed to initiate requests at the same time"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:273
msgid "Idle Timeout"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:274
msgid "DoH/TCP/DoT Connection Multiplexing idle timeout (default 30 seconds)"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:279
msgid "TCP/DoT Connection Multiplexing"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:280
msgid ""
"Enable TCP/DoT RFC 7766 new Query Pipelining connection multiplexing mode"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:285
msgid "Disable TLS Certificate"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:286
msgid ""
"Disable TLS Servers certificate validation, Can be useful if system CA "
"certificate expires or the system time is out of order"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:292
msgid "Enable EDNS client subnet"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:297
msgid "IP Address"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:298
msgid ""
"Please provide the IP address you use when accessing foreign websites. This "
"IP subnet (0/24) will be used as the ECS address for Remote / Streaming "
"Media DNS requests"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:299
msgid ""
"This feature is typically used when using a self-built DNS server as an "
"Remote / Streaming Media DNS upstream (requires support from the upstream "
"server)"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:303
msgid "Prevent DNS Leaks"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:304
msgid "Enable this option fallback policy forces forwarding to remote DNS"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:309
msgid "Enable DNS Cache"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:314
msgid "DNS Cache Size"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:319
msgid "Lazy Cache TTL"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:320
msgid ""
"Lazy cache survival time (in second). To disable Lazy Cache, please set to 0."
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:325
msgid "Cache Dump"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:326
msgid "Save the cache locally and reload the cache dump on the next startup"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:332
msgid "Auto Save Cache Interval"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:337
msgid "Minimum TTL"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:338
msgid ""
"Modify the Minimum TTL value (seconds) for DNS answer results, 0 indicating "
"no modification"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:343
msgid "Maximum TTL"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:344
msgid ""
"Modify the Maximum TTL value (seconds) for DNS answer results, 0 indicating "
"no modification"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:349
msgid "Disable RR Type 65 (HTTPS/SVCB)"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:350
msgid ""
"Block DNS RR Type 65 records (HTTPS/SVCB, used for HTTP/3, ECH, etc.), force "
"using only A/AAAA records."
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:354
msgid "Enable DNS ADblock"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:358
msgid "ADblock Source"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:359
msgid ""
"When using custom rule sources, please use rule types supported by MosDNS "
"(domain lists)."
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:361
msgid "Support for local files, such as: file:///var/mosdns/example.txt"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:371
msgid ""
"Match the parsing result with the Cloudflare IP ranges, and when there is a "
"successful match, \t\t\t\tuse the 'Custom IP' as the parsing result "
"(experimental feature)"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:377
msgid "Custom IP"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:382
msgid "Cloudflare IP Ranges"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:383
msgid ""
"IPv4 CIDR: <a href=\"https://www.cloudflare.com/ips-v4\" target=\"_blank"
"\">https://www.cloudflare.com/ips-v4</a> <br /> IPv6 CIDR: <a href=\"https://"
"www.cloudflare.com/ips-v6\" target=\"_blank\">https://www.cloudflare.com/ips-"
"v6</a>"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:402
msgid "API Listen port"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:408
msgid ""
"Flushing DNS Cache will clear any IP addresses or DNS records from MosDNS "
"cache."
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:410
msgid "Flush DNS Cache"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:433
msgid "Configuration Editor"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:434
msgid ""
"This is the content of the file '/etc/mosdns/config_custom.yaml' from which "
"your MosDNS configuration will be generated. \t\t\tOnly accepts "
"configuration content in yaml format."
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:455
#: htdocs/luci-static/resources/view/mosdns/rules.js:53
#: htdocs/luci-static/resources/view/mosdns/rules.js:59
#: htdocs/luci-static/resources/view/mosdns/rules.js:83
#: htdocs/luci-static/resources/view/mosdns/rules.js:89
#: htdocs/luci-static/resources/view/mosdns/rules.js:113
#: htdocs/luci-static/resources/view/mosdns/rules.js:119
#: htdocs/luci-static/resources/view/mosdns/rules.js:143
#: htdocs/luci-static/resources/view/mosdns/rules.js:149
#: htdocs/luci-static/resources/view/mosdns/rules.js:173
#: htdocs/luci-static/resources/view/mosdns/rules.js:179
#: htdocs/luci-static/resources/view/mosdns/rules.js:203
#: htdocs/luci-static/resources/view/mosdns/rules.js:209
#: htdocs/luci-static/resources/view/mosdns/rules.js:233
#: htdocs/luci-static/resources/view/mosdns/rules.js:239
#: htdocs/luci-static/resources/view/mosdns/rules.js:263
#: htdocs/luci-static/resources/view/mosdns/rules.js:269
#, javascript-format
msgid "Unable to save contents: %s"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:460
msgid "GeoSite Tags"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:461
msgid "Enter the GeoSite.dat category to be exported, Allow add multiple tags"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:462
#: htdocs/luci-static/resources/view/mosdns/basic.js:467
msgid "Export directory: /var/mosdns"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:465
msgid "GeoIP Tags"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/basic.js:466
msgid "Enter the GeoIP.dat category to be exported, Allow add multiple tags"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/logs.js:27
msgid "No log data."
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/logs.js:43
msgid "Failed to clean logs."
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/logs.js:65
msgid "Clear logs"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/logs.js:70
msgid "Log Data"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/logs.js:75
#, javascript-format
msgid "Refresh every %s seconds."
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/rules.js:17
msgid "Rule Settings"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/rules.js:18
msgid "The list of rules only apply to 'Default Config' profiles."
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/rules.js:24
msgid "White Lists"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/rules.js:25
msgid "Block Lists"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/rules.js:26
msgid "Grey Lists"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/rules.js:27
msgid "DDNS Lists"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/rules.js:28
msgid "Hosts"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/rules.js:29
msgid "Redirect"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/rules.js:30
msgid "Block PTR"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/rules.js:31
msgid "Streaming Media"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/rules.js:37
msgid ""
"Added domain names always permit resolution using 'local DNS' with the "
"highest priority (one domain per line, supports domain matching rules)."
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/rules.js:67
msgid ""
"Added domain names will block DNS resolution (one domain per line, supports "
"domain matching rules)."
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/rules.js:97
msgid ""
"Added domain names will always use 'Remote DNS' for resolution (one domain "
"per line, supports domain matching rules)."
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/rules.js:127
msgid ""
"Added domain names will always use 'Local DNS' for resolution, with a forced "
"TTL of 5 seconds, and results will not be cached (one domain per line, "
"supports domain matching rules)."
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/rules.js:157
msgid ""
"Custom Hosts rewrite, for example: baidu.com 10.0.0.1 (one rule per line, "
"supports domain matching rules)."
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/rules.js:187
msgid ""
"Redirecting requests for domain names. Request domain A, but return records "
"for domain B, for example: baidu.com qq.com (one rule per line)."
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/rules.js:217
msgid ""
"Added domain names will block PTR requests (one domain per line, supports "
"domain matching rules)."
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/rules.js:247
msgid ""
"When enabling 'Custom Stream Media DNS', added domains will always use the "
"'Streaming Media DNS server' for resolution (one domain per line, supports "
"domain matching rules)."
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/rules.js:284
#: htdocs/luci-static/resources/view/mosdns/rules.js:288
#, javascript-format
msgid "Failed to restart mosdns: %s"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/update.js:9
msgid "Updating..."
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/update.js:10
msgid "Please wait, this may take a few moments..."
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/update.js:16
msgid "Update success"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/update.js:19
msgid "Update failed, Please check the network status"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/update.js:23
#, javascript-format
msgid "Update failed: %s"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/update.js:30
msgid "Update GeoIP & GeoSite databases"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/update.js:31
msgid ""
"Automatically update GeoIP and GeoSite databases as well as ad filtering "
"rules through scheduled tasks."
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/update.js:36
msgid "Enable Auto Database Update"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/update.js:39
msgid "Update Cycle"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/update.js:40
msgid "Every Day"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/update.js:41
msgid "Every Monday"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/update.js:42
msgid "Every Tuesday"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/update.js:43
msgid "Every Wednesday"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/update.js:44
msgid "Every Thursday"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/update.js:45
msgid "Every Friday"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/update.js:46
msgid "Every Saturday"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/update.js:47
msgid "Every Sunday"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/update.js:50
msgid "Update Time"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/update.js:56
msgid "GeoIP Type"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/update.js:57
msgid "Little: only include Mainland China and Private IP addresses."
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/update.js:59
msgid "Full: includes all Countries and Private IP addresses."
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/update.js:61
msgid "Full"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/update.js:62
msgid "Little"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/update.js:66
msgid "GitHub Proxy"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/update.js:67
msgid ""
"Update data files with GitHub Proxy, leave blank to disable proxy downloads."
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/update.js:68
msgid "https://gh-proxy.com"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/update.js:73
msgid "Check And Update GeoData."
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/update.js:74
msgid "Database Update"
msgstr ""
#: htdocs/luci-static/resources/view/mosdns/update.js:75
msgid "Check And Update"
msgstr ""
#: root/usr/share/luci/menu.d/luci-app-mosdns.json:14
msgid "Basic Setting"
msgstr ""
#: root/usr/share/luci/menu.d/luci-app-mosdns.json:22
msgid "Rules"
msgstr ""
#: root/usr/share/luci/menu.d/luci-app-mosdns.json:30
msgid "Geodata Update"
msgstr ""
#: root/usr/share/luci/menu.d/luci-app-mosdns.json:38
msgid "Logs"
msgstr ""
File diff suppressed because it is too large. Load diff
+25 -22
View File
@@ -1,6 +1,6 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2020-2022, IrineSistiana
# Copyright (C) 2023-2024, sbwml <admin@cooluc.com>
# Copyright (C) 2023-2026, sbwml <admin@cooluc.com>
START=75
USE_PROCD=1
@@ -10,7 +10,7 @@ CONF=$(uci -q get mosdns.config.configfile)
CRON_FILE=/etc/crontabs/root
DUMP_FILE=/etc/mosdns/cache.dump
DUMP_FILE_DEFAULT=/usr/share/mosdns/cache.dump
MOSDNS_SCRIPT=/usr/share/mosdns/mosdns.sh
MOSDNS_SCRIPT=/usr/share/mosdns/mosdns.uc
get_config() {
config_get enabled $1 enabled 0
@@ -41,7 +41,7 @@ get_config() {
config_get custom_stream_media_dns $1 custom_stream_media_dns 0
config_get stream_media_dns $1 stream_media_dns "tls://8.8.8.8"
config_get bootstrap_dns $1 bootstrap_dns "119.29.29.29"
config_get listen_port_api $1 listen_port_api 9091
config_get listen_port_api $1 listen_port_api 52001
config_get concurrent $1 concurrent 1
config_get insecure_skip_verify $1 insecure_skip_verify 0
config_get idle_timeout $1 idle_timeout 30
@@ -178,7 +178,8 @@ generate_config() {
json_add_string "type" "domain_set"
json_add_object "args"
json_add_array "files"
adlist=$($MOSDNS_SCRIPT adlist)
adlist=$($MOSDNS_SCRIPT get_adlist)
[ -z "$adlist" ] && adlist="/var/mosdns/disable-ads.txt" # fail-safe
for list in $adlist; do
json_add_string "" "$list"
done
@@ -256,7 +257,8 @@ generate_config() {
json_add_object "args"
json_add_int "concurrent" "$concurrent"
json_add_array "upstreams"
local_dns=$($MOSDNS_SCRIPT dns)
local_dns=$($MOSDNS_SCRIPT interface_dns)
[ -z "$local_dns" ] && local_dns="119.29.29.29 223.5.5.5" # fail-safe
for addr in $local_dns; do
enable_http3=0
if echo "$addr" | grep -q "^h3://"; then
@@ -730,31 +732,26 @@ reload_service() {
}
setcron() {
sed -i '/mosdns.sh/d' $CRON_FILE 2>/dev/null
[ "$geo_auto_update" -eq 1 ] && echo "0 $geo_update_day_time * * $geo_update_week_time $MOSDNS_SCRIPT geodata" >> $CRON_FILE
sed -i '/mosdns.uc/d' $CRON_FILE 2>/dev/null
[ "$geo_auto_update" -eq 1 ] && echo "0 $geo_update_day_time * * $geo_update_week_time /usr/share/mosdns/mosdns.uc update" >> $CRON_FILE
crontab $CRON_FILE
}
delcron() {
sed -i '/mosdns.sh/d' $CRON_FILE 2>/dev/null
sed -i '/mosdns.uc/d' $CRON_FILE 2>/dev/null
crontab $CRON_FILE
}
v2dat_dump() {
$MOSDNS_SCRIPT v2dat_dump
}
start_service() {
config_load "mosdns"
config_foreach get_config "mosdns"
[ $enabled -ne 1 ] && return 1
delcron ; setcron
:> $($MOSDNS_SCRIPT logfile)
if [ "${log_level}" = "error" ] || [ "${log_level}" = "warn" ]; then
v2dat_dump > /dev/null 2>&1
else
v2dat_dump >> $($MOSDNS_SCRIPT logfile) 2>&1
fi
rm -rf /tmp/log/mosdns*
$MOSDNS_SCRIPT v2dat_dump
[ "${CONF}" = "/var/etc/mosdns.json" ] && generate_config
procd_open_instance mosdns
@@ -766,9 +763,11 @@ start_service() {
procd_set_param stderr 1
procd_set_param respawn
procd_close_instance mosdns
[ "$redirect" -ne 1 ] && [ -f "/etc/mosdns/redirect.lock" ] && restore_setting
[ "$redirect" -eq 1 ] && redirect_setting
reload_dnsmasq
# dns hijack
if [ "$local_dns_redirect" -eq 1 ] && [ -f "/sbin/fw4" ]; then
! nft --check list table inet mosdns > "/dev/null" 2>&1 || \
@@ -777,13 +776,13 @@ start_service() {
nft add chain inet mosdns prerouting "{ type nat hook prerouting priority -95; policy accept; }"
nft add rule inet mosdns prerouting "meta nfproto { ipv4, ipv6 } udp dport 53 counter redirect to :$listen_port comment \"DNS HIJACK\""
fi
# Update Adlist
update_list=0
if [ "$adblock" -eq 1 ]; then
if [ -f "/etc/mosdns/rule/.ad_source" ]; then
for url in $ad_source;
do
if [ "$url" = "geosite.dat" ] || [ $(echo "$url" | grep -c -E "^file://") -eq 1 ]; then
for url in $ad_source; do
if [ "$url" = "geosite.dat" ] ||[ $(echo "$url" | grep -c -E "^file://") -eq 1 ]; then
continue
fi
if [ $(grep -c "$url" "/etc/mosdns/rule/.ad_source") -eq 0 ]; then
@@ -795,7 +794,11 @@ start_service() {
update_list=1
fi
fi
[ "$update_list" -eq 1 ] && $MOSDNS_SCRIPT adlist_update &> /dev/null &
[ "$update_list" -eq 1 ] && {
sleep 3
$MOSDNS_SCRIPT update_adlist
} &
}
stop_service() {
@@ -1,210 +0,0 @@
#!/bin/sh
script_action=${1}
logfile_path() {
configfile=$(uci -q get mosdns.config.configfile)
if [ "$configfile" = "/var/etc/mosdns.json" ]; then
uci -q get mosdns.config.log_file
else
[ ! -f /etc/mosdns/config_custom.yaml ] && exit 1
awk '/^log:/{f=1;next}f==1{if($0~/file:/){print;exit}if($0~/^[^ ]/)exit}' /etc/mosdns/config_custom.yaml | grep -Eo "/[^'\"]+"
fi
}
print_logfile() {
cat $(logfile_path);
}
clean_logfile() {
true > $(logfile_path);
}
interface_dns() (
if [ "$(uci -q get mosdns.config.custom_local_dns)" = 1 ]; then
uci -q get mosdns.config.local_dns
else
peerdns=$(uci -q get network.wan.peerdns)
proto=$(uci -q get network.wan.proto)
if [ "$peerdns" = 0 ] || [ "$proto" = "static" ]; then
uci -q get network.wan.dns
else
interface_status=$(ubus call network.interface.wan status)
echo $interface_status | jsonfilter -e "@['dns-server'][0]"
echo $interface_status | jsonfilter -e "@['dns-server'][1]"
fi
[ $? -ne 0 ] && echo "119.29.29.29 223.5.5.5"
fi
)
get_adlist() (
adblock=$(uci -q get mosdns.config.adblock)
if [ "$adblock" = 1 ]; then
mkdir -p /etc/mosdns/rule/adlist
ad_source=$(uci -q get mosdns.config.ad_source)
for url in $ad_source;
do
if [ $(echo $url) = 'geosite.dat' ]; then
echo "/var/mosdns/geosite_category-ads-all.txt"
elif echo "$url" | grep -Eq "^file://" ; then
echo "$url" | sed 's/file:\/\///'
else
echo "/etc/mosdns/rule/adlist/$(basename $url)"
[ ! -f "/etc/mosdns/rule/adlist/$(basename $url)" ] && touch /etc/mosdns/rule/adlist/$(basename $url)
fi
done
else
rm -rf /etc/mosdns/rule/adlist /etc/mosdns/rule/.ad_source
touch /var/mosdns/disable-ads.txt
echo "/var/mosdns/disable-ads.txt"
fi
)
adlist_update() {
[ "$(uci -q get mosdns.config.adblock)" != 1 ] && return 0
lock_file=/var/lock/mosdns_ad_update.lock
ad_source=$(uci -q get mosdns.config.ad_source)
: > /etc/mosdns/rule/.ad_source
if [ -f "$lock_file" ]; then
has_update=0
exit 0
else
: > $lock_file
fi
AD_TMPDIR=$(mktemp -d) || exit 1
has_update=0
for url in $ad_source;
do
if [ "$url" != "geosite.dat" ] && [ $(echo "$url" | grep -c -E "^file://") -eq 0 ]; then
has_update=1
echo "$url" >> /etc/mosdns/rule/.ad_source
filename=$(basename $url)
if echo "$url" | grep -Eq "^https://raw.githubusercontent.com" ; then
[ -n "$(uci -q get mosdns.config.github_proxy)" ] && mirror="$(uci -q get mosdns.config.github_proxy)/"
else
mirror=""
fi
echo -e "Downloading $mirror$url"
curl --connect-timeout 5 -m 90 --ipv4 -kfSLo "$AD_TMPDIR/$filename" "$mirror$url"
fi
done
if [ $? -ne 0 ]; then
echo -e "\e[1;31mRules download failed."
rm -rf "$AD_TMPDIR" "$lock_file"
exit 1
else
[ $has_update -eq 1 ] && {
mkdir -p /etc/mosdns/rule/adlist
rm -rf /etc/mosdns/rule/adlist/*
\cp $AD_TMPDIR/* /etc/mosdns/rule/adlist
}
fi
rm -rf "$AD_TMPDIR" "$lock_file"
}
geodat_update() (
TMPDIR=$(mktemp -d) || exit 1
[ -n "$(uci -q get mosdns.config.github_proxy)" ] && mirror="$(uci -q get mosdns.config.github_proxy)/"
# geoip.dat - cn-private
geoip_type=$(uci -q get mosdns.config.geoip_type || echo "geoip-only-cn-private")
echo -e "Downloading "$mirror"https://github.com/Loyalsoldier/geoip/releases/latest/download/"$geoip_type".dat"
curl --connect-timeout 5 -m 120 --ipv4 -kfSLo "$TMPDIR/geoip.dat" ""$mirror"https://github.com/Loyalsoldier/geoip/releases/latest/download/"$geoip_type".dat"
[ $? -ne 0 ] && rm -rf "$TMPDIR" && exit 1
# checksum - geoip.dat
echo -e "Downloading "$mirror"https://github.com/Loyalsoldier/geoip/releases/latest/download/"$geoip_type".dat.sha256sum"
curl --connect-timeout 5 -m 20 --ipv4 -kfSLo "$TMPDIR/geoip.dat.sha256sum" ""$mirror"https://github.com/Loyalsoldier/geoip/releases/latest/download/"$geoip_type".dat.sha256sum"
[ $? -ne 0 ] && rm -rf "$TMPDIR" && exit 1
if [ "$(sha256sum "$TMPDIR/geoip.dat" | awk '{print $1}')" != "$(cat "$TMPDIR/geoip.dat.sha256sum" | awk '{print $1}')" ]; then
echo -e "\e[1;31mgeoip.dat checksum error"
rm -rf "$TMPDIR"
exit 1
fi
# geosite.dat
echo -e "Downloading "$mirror"https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat"
curl --connect-timeout 5 -m 120 --ipv4 -kfSLo "$TMPDIR/geosite.dat" ""$mirror"https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat"
[ $? -ne 0 ] && rm -rf "$TMPDIR" && exit 1
# checksum - geosite.dat
echo -e "Downloading "$mirror"https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat.sha256sum"
curl --connect-timeout 5 -m 20 --ipv4 -kfSLo "$TMPDIR/geosite.dat.sha256sum" ""$mirror"https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat.sha256sum"
[ $? -ne 0 ] && rm -rf "$TMPDIR" && exit 1
if [ "$(sha256sum "$TMPDIR/geosite.dat" | awk '{print $1}')" != "$(cat "$TMPDIR/geosite.dat.sha256sum" | awk '{print $1}')" ]; then
echo -e "\e[1;31mgeosite.dat checksum error"
rm -rf "$TMPDIR"
exit 1
fi
rm -rf "$TMPDIR"/*.sha256sum
\cp -a "$TMPDIR"/* /usr/share/v2ray
rm -rf "$TMPDIR"
)
restart_service() {
/etc/init.d/mosdns restart
}
flush_cache() {
curl -s 127.0.0.1:$(uci -q get mosdns.config.listen_port_api)/plugins/lazy_cache/flush || exit 1
}
v2dat_dump() {
# env
v2dat_dir=/usr/share/v2ray
adblock=$(uci -q get mosdns.config.adblock)
ad_source=$(uci -q get mosdns.config.ad_source)
configfile=$(uci -q get mosdns.config.configfile)
streaming_media=$(uci -q get mosdns.config.custom_stream_media_dns)
mkdir -p /var/mosdns
rm -f /var/mosdns/geo*.txt
if [ "$configfile" = "/var/etc/mosdns.json" ]; then
# default config
v2dat unpack geoip -o /var/mosdns -f cn $v2dat_dir/geoip.dat
v2dat unpack geosite -o /var/mosdns -f cn -f apple -f 'geolocation-!cn' $v2dat_dir/geosite.dat
[ "$adblock" = 1 ] && [ $(echo $ad_source | grep -c geosite.dat) -ge '1' ] && v2dat unpack geosite -o /var/mosdns -f category-ads-all $v2dat_dir/geosite.dat
[ "$streaming_media" = 1 ] && v2dat unpack geosite -o /var/mosdns -f netflix -f disney -f hulu $v2dat_dir/geosite.dat || \
touch /var/mosdns/geosite_disney.txt ; touch /var/mosdns/geosite_netflix.txt ; touch /var/mosdns/geosite_hulu.txt
else
# custom config
v2dat unpack geoip -o /var/mosdns -f cn $v2dat_dir/geoip.dat
v2dat unpack geosite -o /var/mosdns -f cn -f 'geolocation-!cn' $v2dat_dir/geosite.dat
geoip_tags=$(uci -q get mosdns.config.geoip_tags)
geosite_tags=$(uci -q get mosdns.config.geosite_tags)
[ -n "$geoip_tags" ] && v2dat unpack geoip -o /var/mosdns $(echo $geoip_tags | sed -r 's/\S+/-f &/g') $v2dat_dir/geoip.dat
[ -n "$geosite_tags" ] && v2dat unpack geosite -o /var/mosdns $(echo $geosite_tags | sed -r 's/\S+/-f &/g') $v2dat_dir/geosite.dat
fi
}
case $script_action in
"dns")
interface_dns
;;
"adlist")
get_adlist
;;
"geodata")
geodat_update && adlist_update && restart_service
;;
"logfile")
logfile_path
;;
"adlist_update")
adlist_update && [ "$has_update" -eq 1 ] && restart_service
;;
"flush")
flush_cache
;;
"v2dat_dump")
v2dat_dump
;;
"printlog")
print_logfile
;;
"cleanlog")
clean_logfile
;;
"version")
mosdns version
;;
*)
exit 0
;;
esac
+298
View File
@@ -0,0 +1,298 @@
#!/usr/bin/env ucode
'use strict';
import { popen, mkdir, unlink, writefile, open, stat} from 'fs';
import { cursor } from 'uci';
import { connect } from 'ubus';
function to_array(val) {
let res =[];
if (type(val) == 'array') {
for (let i = 0; i < length(val); i++) {
if (type(val[i]) == 'string') {
let s = replace(val[i], /^\s+|\s+$/g, '');
if (s != "") push(res, s);
}
}
} else if (type(val) == 'string') {
let parts = split(val, /[ \t\n]+/);
for (let i = 0; i < length(parts); i++) {
if (parts[i] != "") push(res, parts[i]);
}
}
return res;
}
function exec_sys(cmd) {
let p = popen(cmd + " 2>&1", "r");
if (!p) return { code: -1, stdout: "" };
let stdout = p.read("all");
let code = p.close();
if (type(stdout) == 'string') {
stdout = replace(stdout, /^\s+|\s+$/g, '');
}
return { code: code, stdout: stdout || "" };
}
function interface_dns() {
let uci_cursor = cursor();
uci_cursor.load('mosdns');
let dns_list =[];
if (uci_cursor.get('mosdns', 'config', 'custom_local_dns') === '1') {
dns_list = to_array(uci_cursor.get('mosdns', 'config', 'local_dns'));
} else {
uci_cursor.load('network');
let peerdns = uci_cursor.get('network', 'wan', 'peerdns');
let proto = uci_cursor.get('network', 'wan', 'proto');
if (peerdns === '0' || proto === 'static') {
dns_list = to_array(uci_cursor.get('network', 'wan', 'dns'));
} else {
let ubus_conn = connect();
if (ubus_conn) {
let status = ubus_conn.call('network.interface.wan', 'status');
if (status && type(status['dns-server']) == 'array' && length(status['dns-server']) > 0) {
dns_list = status['dns-server'];
}
}
}
}
if (length(dns_list) === 0) {
dns_list =['119.29.29.29', '223.5.5.5'];
}
print(join(" ", dns_list) + "\n");
}
function get_adlist() {
let uci_cursor = cursor();
uci_cursor.load('mosdns');
let adblock = uci_cursor.get('mosdns', 'config', 'adblock');
if (adblock !== '1') {
mkdir('/etc/mosdns/rule', 0755);
exec_sys('rm -rf /etc/mosdns/rule/adlist /etc/mosdns/rule/.ad_source');
writefile('/var/mosdns/disable-ads.txt', '');
print("/var/mosdns/disable-ads.txt\n");
return;
}
mkdir('/etc/mosdns/rule/adlist', 0755);
let ad_source = to_array(uci_cursor.get('mosdns', 'config', 'ad_source'));
let adlist =[];
for (let i = 0; i < length(ad_source); i++) {
let url = ad_source[i];
if (!url) continue;
if (url === 'geosite.dat') {
push(adlist, '/var/mosdns/geosite_category-ads-all.txt');
} else if (index(url, 'file://') === 0) {
push(adlist, substr(url, 7));
} else {
let parts = split(url, '/');
let filename = parts[length(parts) - 1];
let local_path = `/etc/mosdns/rule/adlist/${filename}`;
if (!stat(local_path)) {
writefile(local_path, '');
}
push(adlist, local_path);
}
}
print(join("\n", adlist) + "\n");
}
function update_adlist() {
let uci_cursor = cursor();
uci_cursor.load('mosdns');
if (uci_cursor.get('mosdns', 'config', 'adblock') !== '1') {
return false;
}
let lock_file = '/var/lock/mosdns_ad_update.lock';
let ad_source = to_array(uci_cursor.get('mosdns', 'config', 'ad_source'));
let github_proxy = uci_cursor.get('mosdns', 'config', 'github_proxy') || '';
mkdir('/etc/mosdns/rule', 0755);
writefile('/etc/mosdns/rule/.ad_source', '');
if (stat(lock_file)) return false;
writefile(lock_file, '');
let tmp_res = exec_sys('mktemp -d');
if (tmp_res.code !== 0) {
unlink(lock_file);
die("Failed to create temp directory for adlist.");
}
let ad_tmpdir = tmp_res.stdout;
let has_update = false;
let download_failed = false;
for (let i = 0; i < length(ad_source); i++) {
let url = ad_source[i];
if (!url) continue;
if (url !== 'geosite.dat' && index(url, 'file://') !== 0) {
has_update = true;
exec_sys(`echo "${url}" >> /etc/mosdns/rule/.ad_source`);
let parts = split(url, '/');
let filename = parts[length(parts) - 1];
let mirror = "";
if (match(url, /^https:\/\/raw\.githubusercontent\.com/)) {
mirror = github_proxy ? github_proxy + '/' : '';
}
print(`Downloading ${mirror}${url}\n`);
let curl_res = exec_sys(`curl --connect-timeout 5 -m 90 --ipv4 -kfSLo "${ad_tmpdir}/${filename}" "${mirror}${url}"`);
if (curl_res.code !== 0) download_failed = true;
}
}
if (download_failed) {
print("\x1b[1;31mRules download failed.\n");
exec_sys(`rm -rf "${ad_tmpdir}"`);
unlink(lock_file);
exit(1);
} else {
if (has_update) {
mkdir('/etc/mosdns/rule/adlist', 0755);
exec_sys('rm -rf /etc/mosdns/rule/adlist/*');
exec_sys(`cp "${ad_tmpdir}"/* /etc/mosdns/rule/adlist/`);
}
}
exec_sys(`rm -rf "${ad_tmpdir}"`);
unlink(lock_file);
return has_update;
}
function update_geodat() {
let uci_cursor = cursor();
uci_cursor.load('mosdns');
let github_proxy = uci_cursor.get('mosdns', 'config', 'github_proxy') || '';
let mirror = github_proxy ? github_proxy + '/' : '';
let geoip_type = uci_cursor.get('mosdns', 'config', 'geoip_type') || 'geoip-only-cn-private';
let v2dat_dir = '/usr/share/v2ray';
let tmp_res = exec_sys('mktemp -d');
if (tmp_res.code !== 0) exit(1);
let tmpdir = tmp_res.stdout;
let geoip_url = mirror + "https://github.com/Loyalsoldier/geoip/releases/latest/download/" + geoip_type + ".dat";
print(`Downloading ${geoip_url}\n`);
if (exec_sys(`curl --connect-timeout 5 -m 120 --ipv4 -kfSLo "${tmpdir}/geoip.dat" "${geoip_url}"`).code !== 0) {
exec_sys(`rm -rf "${tmpdir}"`); exit(1);
}
print(`Downloading ${geoip_url}.sha256sum\n`);
if (exec_sys(`curl --connect-timeout 5 -m 20 --ipv4 -kfSLo "${tmpdir}/geoip.dat.sha256sum" "${geoip_url}.sha256sum"`).code !== 0) {
exec_sys(`rm -rf "${tmpdir}"`); exit(1);
}
let sum_local = split(exec_sys(`sha256sum "${tmpdir}/geoip.dat"`).stdout, /[ \t\n]+/)[0];
let sum_remote = split(exec_sys(`cat "${tmpdir}/geoip.dat.sha256sum"`).stdout, /[ \t\n]+/)[0];
if (sum_local !== sum_remote) {
print("\x1b[1;31mgeoip.dat checksum error\n");
exec_sys(`rm -rf "${tmpdir}"`); exit(1);
}
let geosite_url = mirror + "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat";
print(`Downloading ${geosite_url}\n`);
if (exec_sys(`curl --connect-timeout 5 -m 120 --ipv4 -kfSLo "${tmpdir}/geosite.dat" "${geosite_url}"`).code !== 0) {
exec_sys(`rm -rf "${tmpdir}"`); exit(1);
}
print(`Downloading ${geosite_url}.sha256sum\n`);
if (exec_sys(`curl --connect-timeout 5 -m 20 --ipv4 -kfSLo "${tmpdir}/geosite.dat.sha256sum" "${geosite_url}.sha256sum"`).code !== 0) {
exec_sys(`rm -rf "${tmpdir}"`); exit(1);
}
sum_local = split(exec_sys(`sha256sum "${tmpdir}/geosite.dat"`).stdout, /[ \t\n]+/)[0];
sum_remote = split(exec_sys(`cat "${tmpdir}/geosite.dat.sha256sum"`).stdout, /[ \t\n]+/)[0];
if (sum_local !== sum_remote) {
print("\x1b[1;31mgeosite.dat checksum error\n");
exec_sys(`rm -rf "${tmpdir}"`); exit(1);
}
exec_sys(`rm -rf "${tmpdir}"/*.sha256sum`);
exec_sys(`cp -a "${tmpdir}"/* "${v2dat_dir}/"`);
exec_sys(`rm -rf "${tmpdir}"`);
}
function v2dat_dump() {
let uci_cursor = cursor();
uci_cursor.load('mosdns');
let v2dat_dir = '/usr/share/v2ray';
let configfile = uci_cursor.get('mosdns', 'config', 'configfile') || '/var/etc/mosdns.json';
let adblock = uci_cursor.get('mosdns', 'config', 'adblock');
let ad_source = uci_cursor.get('mosdns', 'config', 'ad_source') || "";
let streaming_media = uci_cursor.get('mosdns', 'config', 'custom_stream_media_dns');
mkdir('/var/mosdns', 0755);
exec_sys('rm -f /var/mosdns/geo*.txt');
if (configfile === "/var/etc/mosdns.json") {
exec_sys(`v2dat unpack geoip -o /var/mosdns -f cn ${v2dat_dir}/geoip.dat`);
exec_sys(`v2dat unpack geosite -o /var/mosdns -f cn -f apple -f 'geolocation-!cn' ${v2dat_dir}/geosite.dat`);
if (adblock === '1' && index(ad_source, 'geosite.dat') !== -1) {
exec_sys(`v2dat unpack geosite -o /var/mosdns -f category-ads-all ${v2dat_dir}/geosite.dat`);
}
if (streaming_media === '1') {
exec_sys(`v2dat unpack geosite -o /var/mosdns -f netflix -f disney -f hulu ${v2dat_dir}/geosite.dat`);
} else {
writefile('/var/mosdns/geosite_disney.txt', '');
writefile('/var/mosdns/geosite_netflix.txt', '');
writefile('/var/mosdns/geosite_hulu.txt', '');
}
} else {
exec_sys(`v2dat unpack geoip -o /var/mosdns -f cn ${v2dat_dir}/geoip.dat`);
exec_sys(`v2dat unpack geosite -o /var/mosdns -f cn -f 'geolocation-!cn' ${v2dat_dir}/geosite.dat`);
let geoip_tags = to_array(uci_cursor.get('mosdns', 'config', 'geoip_tags'));
if (length(geoip_tags) > 0) {
let tags_str = "-f '" + join("' -f '", geoip_tags) + "'";
exec_sys(`v2dat unpack geoip -o /var/mosdns ${tags_str} ${v2dat_dir}/geoip.dat`);
}
let geosite_tags = to_array(uci_cursor.get('mosdns', 'config', 'geosite_tags'));
if (length(geosite_tags) > 0) {
let tags_str = "-f '" + join("' -f '", geosite_tags) + "'";
exec_sys(`v2dat unpack geosite -o /var/mosdns ${tags_str} ${v2dat_dir}/geosite.dat`);
}
}
}
let action = ARGV[0];
switch (action) {
case "interface_dns":
interface_dns();
break;
case "get_adlist":
get_adlist();
break;
case "update":
update_geodat();
update_adlist();
exec_sys('/etc/init.d/mosdns restart');
break;
case "update_adlist":
if (update_adlist()) {
exec_sys('/etc/init.d/mosdns restart');
}
break;
case "v2dat_dump":
v2dat_dump();
break;
default:
exit(0);
}
@@ -5,36 +5,33 @@
"file": {
"/etc/init.d/mosdns": [ "exec" ],
"/etc/mosdns/config_custom.yaml": [ "read" ],
"/etc/mosdns/rule/blocklist.txt": [ "read" ],
"/etc/mosdns/rule/cloudflare-cidr.txt": [ "read" ],
"/etc/mosdns/rule/ddnslist.txt": [ "read" ],
"/etc/mosdns/rule/greylist.txt": [ "read" ],
"/etc/mosdns/rule/hosts.txt": [ "read" ],
"/etc/mosdns/rule/local-ptr.txt": [ "read" ],
"/etc/mosdns/rule/redirect.txt": [ "read" ],
"/etc/mosdns/rule/streaming.txt": [ "read" ],
"/etc/mosdns/rule/whitelist.txt": [ "read" ],
"/etc/mosdns/rule/*": [ "read" ],
"/usr/bin/mosdns": [ "exec" ],
"/usr/share/mosdns/mosdns.sh": [ "exec" ]
"/usr/share/mosdns/mosdns.uc": [ "exec" ],
"/var/log/*": [ "read" ],
"/var/mosdns/*": [ "read" ]
},
"ubus": {
"file": [ "read" ],
"service": [ "list" ]
"service": [ "list" ],
"luci.mosdns": [
"clean_log",
"flush_cache",
"get_version",
"print_log",
"restart"
]
},
"uci": [ "mosdns" ]
},
"write": {
"file": {
"/etc/mosdns/config_custom.yaml": [ "write" ],
"/etc/mosdns/rule/blocklist.txt": [ "write" ],
"/etc/mosdns/rule/cloudflare-cidr.txt": [ "write" ],
"/etc/mosdns/rule/ddnslist.txt": [ "write" ],
"/etc/mosdns/rule/greylist.txt": [ "write" ],
"/etc/mosdns/rule/hosts.txt": [ "write" ],
"/etc/mosdns/rule/local-ptr.txt": [ "write" ],
"/etc/mosdns/rule/redirect.txt": [ "write" ],
"/etc/mosdns/rule/streaming.txt": [ "write" ],
"/etc/mosdns/rule/whitelist.txt": [ "write" ]
"/etc/mosdns/rule/*": [ "write" ],
"/usr/share/mosdns/*": [ "write" ],
"/usr/share/v2ray/*": [ "write" ],
"/var/log/*": [ "write" ],
"/var/mosdns/*": [ "write" ]
},
"ubus": {
"file": [ "write" ]
@@ -43,4 +40,3 @@
}
}
}
@@ -0,0 +1,126 @@
#!/usr/bin/env ucode
'use strict';
import { popen, writefile, stat, readfile } from 'fs';
import { cursor } from 'uci';
function to_array(val) {
let res =[];
if (type(val) == 'array') {
for (let i = 0; i < length(val); i++) {
if (type(val[i]) == 'string') {
let s = replace(val[i], /^\s+|\s+$/g, '');
if (s != "") push(res, s);
}
}
} else if (type(val) == 'string') {
let parts = split(val, /[ \t\n]+/);
for (let i = 0; i < length(parts); i++) {
if (parts[i] != "") push(res, parts[i]);
}
}
return res;
}
function exec_sys(cmd) {
let p = popen(cmd + " 2>&1", "r");
if (!p) return { code: -1, stdout: "" };
let stdout = p.read("all");
let code = p.close();
if (type(stdout) == 'string') {
stdout = replace(stdout, /^\s+|\s+$/g, '');
}
return { code: code, stdout: stdout || "" };
}
function restart_mosdns() {
let p = popen('(sleep 1; /etc/init.d/mosdns restart) >/dev/null 2>&1 &', 'r');
if (p) p.close();
}
function get_logfile_path_internal() {
let uci_cursor = cursor();
uci_cursor.load('mosdns');
let configfile = uci_cursor.get('mosdns', 'config', 'configfile');
if (configfile === '/var/etc/mosdns.json' || !configfile) {
return uci_cursor.get('mosdns', 'config', 'log_file');
} else {
return '/var/log/mosdns.log';
}
return null;
}
const methods = {
flush_cache: {
call: function() {
try {
let uci_cursor = cursor();
uci_cursor.load('mosdns');
let port = uci_cursor.get('mosdns', 'config', 'listen_port_api');
if (!port) return { error: "API listen port not configured." };
let res = exec_sys(`curl -s 127.0.0.1:${port}/plugins/lazy_cache/flush`);
if (res.code === 0) {
return { success: true };
} else {
return { success: false, error: res.stdout };
}
} catch (e) {
return { error: String(e) };
}
}
},
print_log: {
call: function() {
try {
let path = get_logfile_path_internal();
if (path && stat(path)) {
return { log: readfile(path) };
} else {
return { error: 'Log file not accessible or does not exist.' };
}
} catch (e) {
return { error: String(e) };
}
}
},
clean_log: {
call: function() {
try {
let path = get_logfile_path_internal();
if (path) {
writefile(path, '');
return { success: true };
} else {
return { error: 'Log file path could not be determined.' };
}
} catch (e) {
return { error: String(e) };
}
}
},
get_version: {
call: function() {
let res = exec_sys('mosdns version');
if (res.code === 0) {
return { version: res.stdout };
} else {
return { error: res.stdout };
}
}
},
restart: {
call: function() {
restart_mosdns();
return { code: 0, output: "mosdns is restarting in background." };
}
}
};
return { "luci.mosdns": methods };