⛅ Sync 2026-08-22 23:43:25

This commit is contained in:
github-actions[bot] committed 2026-08-22 23:43:25 +08:00
1 parent 5a64dc251d
commit 3349c20490
16 files changed
+450 -104

No files matched your search

+3 -3
View File
@@ -5,10 +5,10 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=dae
PKG_VERSION:=2026.08.13
PKG_RELEASE:=36
PKG_VERSION:=2026.08.21
PKG_RELEASE:=37
PKG_SOURCE:=dae-src-2026.08.13-0d20959710a0.tar.gz
PKG_SOURCE:=dae-src-2026.08.21-8138f66f2c6d.tar.gz
PKG_SOURCE_URL:=https://github.com/kenzok8/openwrt-daede/releases/download/dae-src
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
PKG_HASH:=skip
+3 -3
View File
@@ -5,10 +5,10 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=daed
PKG_VERSION:=2026.08.13
PKG_RELEASE:=47
PKG_VERSION:=2026.08.21
PKG_RELEASE:=48
PKG_SOURCE:=daed-src-2026.08.13-4a38e0f66b3d.tar.gz
PKG_SOURCE:=daed-src-2026.08.21-aeef51da973f.tar.gz
PKG_SOURCE_URL:=https://github.com/kenzok8/openwrt-daede/releases/download/daed-src
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
PKG_HASH:=skip
+2 -2
View File
@@ -5,8 +5,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=internet-detector-mod-email
PKG_VERSION:=1.7.3
PKG_RELEASE:=3
PKG_VERSION:=1.7.4
PKG_RELEASE:=4
PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/luci-app-internet-detector>
include $(INCLUDE_DIR)/package.mk
+2 -2
View File
@@ -5,8 +5,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=internet-detector-mod-modem-restart
PKG_VERSION:=1.7.3
PKG_RELEASE:=3
PKG_VERSION:=1.7.4
PKG_RELEASE:=4
PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/luci-app-internet-detector>
include $(INCLUDE_DIR)/package.mk
+2 -2
View File
@@ -5,8 +5,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=internet-detector-mod-telegram
PKG_VERSION:=1.7.3
PKG_RELEASE:=3
PKG_VERSION:=1.7.4
PKG_RELEASE:=4
PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/luci-app-internet-detector>
include $(INCLUDE_DIR)/package.mk
+2 -2
View File
@@ -5,8 +5,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=internet-detector
PKG_VERSION:=1.7.3
PKG_RELEASE:=5
PKG_VERSION:=1.7.4
PKG_RELEASE:=6
PKG_MAINTAINER:=gSpot <https://github.com/gSpotx2f/luci-app-internet-detector>
include $(INCLUDE_DIR)/package.mk
@@ -12,8 +12,8 @@ local uci = require("uci")
-- Default settings
local InternetDetector = {
appName = "internet-detector",
libDir = "/usr/lib/lua",
appName = "internet-detector",
libDir = "/usr/lib/lua",
logLevels = {
emerg = { level = syslog.LOG_EMERG, num = 0 },
alert = { level = syslog.LOG_ALERT, num = 1 },
@@ -24,18 +24,32 @@ local InternetDetector = {
info = { level = syslog.LOG_INFO, num = 6 },
debug = { level = syslog.LOG_DEBUG, num = 7 },
},
pingCmd = "/bin/ping",
pingParams = "-c 1",
curlExec = "/usr/bin/curl",
curlParams = '-s -g --no-keepalive --head --user-agent "Mozilla/5.0 (X11; Linux x86_64; rv:142.0) Gecko/20100101 Firefox/142.0"',
mode = 0, -- 0: disabled, 1: Service, 2: UI detector
loggingLevel = 6,
hostname = "OpenWrt",
uiRunTime = 30,
noModules = false,
uiAvailModules = { mod_public_ip = true },
debug = false,
serviceConfig = {
pingCmd = "/bin/ping",
pingParams = "-c 1",
curlExec = "/usr/bin/curl",
curlParams = '-s -g --no-keepalive --head --user-agent "Mozilla/5.0 (X11; Linux x86_64; rv:153.0) Gecko/20100101 Firefox/153.0"',
curlHttpOkCodes = {
[200] = true,
[202] = true,
[203] = true,
[204] = true,
[206] = true,
[300] = true,
[301] = true,
[302] = true,
[303] = true,
[304] = true,
[307] = true,
[308] = true,
},
mode = 0, -- 0: disabled, 1: Service, 2: UI detector
loggingLevel = 6,
hostname = "OpenWrt",
uiRunTime = 30,
noModules = false,
uiAvailModules = { mod_public_ip = true },
debug = false,
serviceConfig = {
hosts = {
[1] = "8.8.8.8",
[2] = "1.1.1.1",
@@ -43,7 +57,7 @@ local InternetDetector = {
urls = {
[1] = "https://www.google.com",
},
check_type = 0, -- 0: TCP, 1: ICMP
check_type = 0, -- 0: TCP, 1: ICMP, 2: URL test
tcp_port = 53,
icmp_packet_size = 56,
interval_up = 30,
@@ -58,13 +72,13 @@ local InternetDetector = {
iface = nil,
instance = nil,
},
modules = {},
parsedHosts = {},
proxyAuthString = "",
proxyString = "",
uiCounter = 0,
pidFile = nil,
statusFile = nil,
modules = {},
parsedHosts = {},
proxyAuthString = "",
proxyString = "",
uiCounter = 0,
pidFile = nil,
statusFile = nil,
}
InternetDetector.configDir = string.format("/etc/%s", InternetDetector.appName)
InternetDetector.modulesDir = string.format(
@@ -280,7 +294,6 @@ function InternetDetector:TCPConnectionToHost(host, port)
if not ok then
self:debugOutput(string.format(
"SOCKET ERROR: %s, %s", errMsg, errNum))
unistd.close(sock)
return retCode
end
@@ -380,7 +393,7 @@ function InternetDetector:checkURL(url)
if retCode == 0 and data then
httpCode = self:getHTTPCode(data)
end
return (httpCode ~= 200) and 1 or 0
return (not self.curlHttpOkCodes[httpCode]) and 1 or 0
end
function InternetDetector:exit()
@@ -27,7 +27,7 @@ local Module = {
requestAttempts = 2,
timeout = 3,
curlExec = "/usr/bin/curl",
curlParams = '-s -g --no-keepalive --user-agent "Mozilla/5.0 (X11; Linux x86_64; rv:142.0) Gecko/20100101 Firefox/142.0"',
curlParams = '-s -g --no-keepalive --user-agent "Mozilla/5.0 (X11; Linux x86_64; rv:153.0) Gecko/20100101 Firefox/153.0"',
providers = {
opendns1 = {
name = "opendns1", type = "dns", host = "myip.opendns.com",
+2 -2
View File
@@ -5,8 +5,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-internet-detector
PKG_VERSION:=1.7.3
PKG_RELEASE:=3
PKG_VERSION:=1.7.4
PKG_RELEASE:=4
LUCI_TITLE:=LuCI support for internet-detector
LUCI_DEPENDS:=+internet-detector
LUCI_PKGARCH:=all
+2 -2
View File
@@ -1,8 +1,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-mosdns
PKG_VERSION:=1.7.6
PKG_RELEASE:=13
PKG_VERSION:=1.7.7
PKG_RELEASE:=14
LUCI_TITLE:=LuCI Support for mosdns
LUCI_PKGARCH:=all
@@ -320,6 +320,30 @@ return view.extend({
o.default = 86400;
o.depends('cache', '1');
o = s.taboption('advanced', form.Flag, 'prefetch', _('Cache Prefetching'),
_('Proactively refresh hot cache entries in the background before they expire.'));
o.rmempty = false;
o.default = false;
o.depends('cache', '1');
o = s.taboption('advanced', form.Value, 'prefetch_before_expire', _('Prefetch Before Expire'),
_('Prefetch when the remaining TTL is less than this value (in seconds).'));
o.datatype = 'and(uinteger,min(1))';
o.default = 10;
o.depends('prefetch', '1');
o = s.taboption('advanced', form.Value, 'prefetch_min_hits', _('Prefetch Min Hits'),
_('Minimum cache hits required since the last refresh to trigger a prefetch.'));
o.datatype = 'and(uinteger,min(1))';
o.default = 3;
o.depends('prefetch', '1');
o = s.taboption('advanced', form.Value, 'prefetch_scan_interval', _('Prefetch Scan Interval'),
_('Interval for the background thread to scan the cache for prefetching (in seconds).'));
o.datatype = 'and(uinteger,min(1))';
o.default = 5;
o.depends('prefetch', '1');
o = s.taboption('advanced', form.Flag, 'dump_file', _('Cache Dump'),
_('Save the cache locally and reload the cache dump on the next startup'));
o.rmempty = false;
+66 -30
View File
@@ -5,11 +5,11 @@ msgstr "Content-Type: text/plain; charset=UTF-8"
msgid "360 Public DNS (DNS over HTTPS)"
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:356
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:380
msgid "ADblock Source"
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:395
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:419
msgid "API Listen port"
msgstr ""
@@ -82,7 +82,7 @@ msgstr ""
msgid "Apple domains optimization"
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:330
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:354
msgid "Auto Save Cache Interval"
msgstr ""
@@ -105,7 +105,7 @@ msgstr ""
msgid "Basic Setting"
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:348
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:372
msgid ""
"Block DNS RR Type 65 records (HTTPS/SVCB, used for HTTP/3, ECH, etc.), force "
"using only A/AAAA records."
@@ -129,10 +129,14 @@ msgid ""
"resolvers you specify as upstreams"
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:323
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:347
msgid "Cache Dump"
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:323
msgid "Cache Prefetching"
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:150
msgid "Check And Update"
msgstr ""
@@ -178,7 +182,7 @@ msgstr ""
msgid "CloudFlare Public DNS (1.1.1.1)"
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:380
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:404
msgid "Cloudflare IP Ranges"
msgstr ""
@@ -198,7 +202,7 @@ msgstr ""
msgid "Config File"
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:426
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:450
msgid "Configuration Editor"
msgstr ""
@@ -216,7 +220,7 @@ msgid ""
"supports domain matching rules)."
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:375
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:399
msgid "Custom IP"
msgstr ""
@@ -258,7 +262,7 @@ msgstr ""
msgid "Default Config"
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:347
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:371
msgid "Disable RR Type 65 (HTTPS/SVCB)"
msgstr ""
@@ -280,7 +284,7 @@ msgstr ""
msgid "Enable Auto Database Update"
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:352
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:376
msgid "Enable DNS ADblock"
msgstr ""
@@ -302,15 +306,15 @@ msgid "Enable this option fallback policy forces forwarding to remote DNS"
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:142
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:368
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:392
msgid "Enabled"
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:453
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:477
msgid "Enter the GeoIP.dat category to be exported, Allow add multiple tags"
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:448
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:472
msgid "Enter the GeoSite.dat category to be exported, Allow add multiple tags"
msgstr ""
@@ -350,8 +354,8 @@ msgstr ""
msgid "Every Wednesday"
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:449
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:454
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:473
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:478
msgid "Export directory: /var/mosdns"
msgstr ""
@@ -363,7 +367,7 @@ msgstr ""
msgid "Failed to start update."
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:403
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:427
msgid "Flush DNS Cache"
msgstr ""
@@ -375,7 +379,7 @@ msgstr ""
msgid "Flushing DNS Cache Success."
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:401
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:425
msgid ""
"Flushing DNS Cache will clear any IP addresses or DNS records from MosDNS "
"cache."
@@ -411,7 +415,7 @@ msgstr ""
msgid "GeoData Export"
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:452
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:476
msgid "GeoIP Tags"
msgstr ""
@@ -419,7 +423,7 @@ msgstr ""
msgid "GeoIP Type"
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:447
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:471
msgid "GeoSite Tags"
msgstr ""
@@ -458,7 +462,7 @@ msgstr ""
msgid "IP Address"
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:381
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:405
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://"
@@ -486,6 +490,12 @@ msgstr ""
msgid "Info"
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:342
msgid ""
"Interval for the background thread to scan the cache for prefetching (in "
"seconds)."
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:317
msgid "Lazy Cache TTL"
msgstr ""
@@ -527,28 +537,33 @@ msgstr ""
msgid "Logs"
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:369
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:393
msgid ""
"Match the parsing result with the Cloudflare IP ranges, and when there is a "
"successful match, use the 'Custom IP' as the parsing result (experimental "
"feature)"
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:341
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:365
msgid "Maximum TTL"
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:335
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:359
msgid "Minimum TTL"
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:342
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:336
msgid ""
"Minimum cache hits required since the last refresh to trigger a prefetch."
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:366
msgid ""
"Modify the Maximum TTL value (seconds) for DNS answer results, 0 indicating "
"no modification"
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:336
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:360
msgid ""
"Modify the Minimum TTL value (seconds) for DNS answer results, 0 indicating "
"no modification"
@@ -589,10 +604,31 @@ msgstr ""
msgid "Please wait, this may take a few moments..."
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:329
msgid "Prefetch Before Expire"
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:335
msgid "Prefetch Min Hits"
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:341
msgid "Prefetch Scan Interval"
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:330
msgid "Prefetch when the remaining TTL is less than this value (in seconds)."
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:301
msgid "Prevent DNS Leaks"
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:324
msgid ""
"Proactively refresh hot cache entries in the background before they expire."
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:227
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:244
msgid "Quad9 Public DNS (149.112.112.112)"
@@ -637,7 +673,7 @@ msgstr ""
msgid "Rules"
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:324
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:348
msgid "Save the cache locally and reload the cache dump on the next startup"
msgstr ""
@@ -653,7 +689,7 @@ msgstr ""
msgid "Streaming Media DNS server"
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:359
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:383
msgid "Support for local files, such as: file:///var/mosdns/example.txt"
msgstr ""
@@ -686,7 +722,7 @@ msgid ""
"server)"
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:427
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:451
msgid ""
"This is the content of the file '/etc/mosdns/config_custom.yaml' from which "
"your MosDNS configuration will be generated. Only accepts configuration "
@@ -701,7 +737,7 @@ msgstr ""
msgid "TrafficRoute Public DNS (180.184.2.2)"
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:442
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:466
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:43
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:48
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:67
@@ -765,7 +801,7 @@ msgid ""
"domain matching rules)."
msgstr ""
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:357
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:381
msgid ""
"When using custom rule sources, please use rule types supported by MosDNS "
"(domain list or AdGuardHome rules)."
+66 -30
View File
@@ -15,11 +15,11 @@ msgstr ""
msgid "360 Public DNS (DNS over HTTPS)"
msgstr "360 安全 DNS(DNS over HTTPS)"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:356
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:380
msgid "ADblock Source"
msgstr "广告过滤规则来源"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:395
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:419
msgid "API Listen port"
msgstr "API 监听端口"
@@ -97,7 +97,7 @@ msgstr "另一个更新正在进行中。"
msgid "Apple domains optimization"
msgstr "Apple 域名解析优化"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:330
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:354
msgid "Auto Save Cache Interval"
msgstr "自动保存缓存间隔(秒)"
@@ -120,7 +120,7 @@ msgstr "基本选项"
msgid "Basic Setting"
msgstr "基本设置"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:348
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:372
msgid ""
"Block DNS RR Type 65 records (HTTPS/SVCB, used for HTTP/3, ECH, etc.), force "
"using only A/AAAA records."
@@ -146,10 +146,14 @@ msgid ""
"resolvers you specify as upstreams"
msgstr "Bootstrap DNS 服务器用于解析您指定为上游的 DoH / DoT 解析器的 IP 地址"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:323
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:347
msgid "Cache Dump"
msgstr "自动保存缓存"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:323
msgid "Cache Prefetching"
msgstr "缓存预读"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js:150
msgid "Check And Update"
msgstr "检查并更新"
@@ -195,7 +199,7 @@ msgstr "CloudFlare 公共 DNS(1.0.0.1)"
msgid "CloudFlare Public DNS (1.1.1.1)"
msgstr "CloudFlare 公共 DNS(1.1.1.1)"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:380
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:404
msgid "Cloudflare IP Ranges"
msgstr "Cloudflare IP 范围"
@@ -215,7 +219,7 @@ msgstr "DNS 服务器并发数(默认 2)"
msgid "Config File"
msgstr "配置文件"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:426
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:450
msgid "Configuration Editor"
msgstr "配置编辑器"
@@ -234,7 +238,7 @@ msgid ""
msgstr ""
"自定义 Hosts 重写,如:baidu.com 10.0.0.1(每个规则一行,支持域名匹配规则)"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:375
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:399
msgid "Custom IP"
msgstr "自选 IP"
@@ -276,7 +280,7 @@ msgstr "调试"
msgid "Default Config"
msgstr "内置预设"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:347
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:371
msgid "Disable RR Type 65 (HTTPS/SVCB)"
msgstr "禁用 RR Type 65 (HTTPS/SVCB)"
@@ -299,7 +303,7 @@ msgstr "DoH/TCP/DoT 连接复用空闲保持时间(默认 30 秒)"
msgid "Enable Auto Database Update"
msgstr "启用自动更新"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:352
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:376
msgid "Enable DNS ADblock"
msgstr "启用 DNS 广告过滤"
@@ -321,15 +325,15 @@ msgid "Enable this option fallback policy forces forwarding to remote DNS"
msgstr "启用此选项 fallback 策略会强制转发到远程 DNS"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:142
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:368
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:392
msgid "Enabled"
msgstr "启用"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:453
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:477
msgid "Enter the GeoIP.dat category to be exported, Allow add multiple tags"
msgstr "输入需要导出的 GeoIP.dat 类别条目,允许添加多个标签"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:448
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:472
msgid "Enter the GeoSite.dat category to be exported, Allow add multiple tags"
msgstr "填写需要导出的 GeoSite.dat 类别条目,允许添加多个标签"
@@ -369,8 +373,8 @@ msgstr "每周二"
msgid "Every Wednesday"
msgstr "每周三"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:449
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:454
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:473
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:478
msgid "Export directory: /var/mosdns"
msgstr "导出目录:/var/mosdns"
@@ -382,7 +386,7 @@ msgstr "清理日志失败:%s"
msgid "Failed to start update."
msgstr "启动更新失败"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:403
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:427
msgid "Flush DNS Cache"
msgstr "刷新 DNS 缓存"
@@ -394,7 +398,7 @@ msgstr "刷新 DNS 缓存失败,请检查 MosDNS 状态是否在运行中。"
msgid "Flushing DNS Cache Success."
msgstr "刷新 DNS 缓存成功"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:401
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:425
msgid ""
"Flushing DNS Cache will clear any IP addresses or DNS records from MosDNS "
"cache."
@@ -430,7 +434,7 @@ msgstr "全量:包含所有国家和私有 IP 地址。"
msgid "GeoData Export"
msgstr "GeoData 导出"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:452
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:476
msgid "GeoIP Tags"
msgstr "GeoIP 标签"
@@ -438,7 +442,7 @@ msgstr "GeoIP 标签"
msgid "GeoIP Type"
msgstr "GeoIP 类型"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:447
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:471
msgid "GeoSite Tags"
msgstr "GeoSite 标签"
@@ -477,7 +481,7 @@ msgstr ""
msgid "IP Address"
msgstr "IP 地址"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:381
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:405
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://"
@@ -505,6 +509,12 @@ msgstr "空闲超时"
msgid "Info"
msgstr "信息"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:342
msgid ""
"Interval for the background thread to scan the cache for prefetching (in "
"seconds)."
msgstr "后台线程扫描缓存以进行预取的时间间隔(单位:秒)"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:317
msgid "Lazy Cache TTL"
msgstr "乐观缓存 TTL"
@@ -546,7 +556,7 @@ msgstr "日志等级"
msgid "Logs"
msgstr "日志"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:369
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:393
#, fuzzy
msgid ""
"Match the parsing result with the Cloudflare IP ranges, and when there is a "
@@ -556,21 +566,26 @@ msgstr ""
"将解析结果与 Cloudflare IP 范围进行匹配,当匹配成功时,使用 “自选 IP” 作为解"
"析结果(实验性功能)"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:341
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:365
msgid "Maximum TTL"
msgstr "覆盖最大 TTL 值(默认 0)"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:335
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:359
msgid "Minimum TTL"
msgstr "覆盖最小 TTL 值(默认 0)"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:342
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:336
msgid ""
"Minimum cache hits required since the last refresh to trigger a prefetch."
msgstr "触发预读所需的最小缓存命中次数(自上次刷新起)"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:366
msgid ""
"Modify the Maximum TTL value (seconds) for DNS answer results, 0 indicating "
"no modification"
msgstr "修改 DNS 应答结果的最大 TTL 值(秒),0 表示不修改"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:336
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:360
msgid ""
"Modify the Minimum TTL value (seconds) for DNS answer results, 0 indicating "
"no modification"
@@ -613,10 +628,31 @@ msgstr ""
msgid "Please wait, this may take a few moments..."
msgstr "请稍候,这可能需要一点时间..."
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:329
msgid "Prefetch Before Expire"
msgstr "预读触发阈值"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:335
msgid "Prefetch Min Hits"
msgstr "预读最小命中次数"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:341
msgid "Prefetch Scan Interval"
msgstr "预读扫描周期"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:330
msgid "Prefetch when the remaining TTL is less than this value (in seconds)."
msgstr "当剩余 TTL 小于此值(秒)时触发预读"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:301
msgid "Prevent DNS Leaks"
msgstr "防止 DNS 泄漏"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:324
msgid ""
"Proactively refresh hot cache entries in the background before they expire."
msgstr "在缓存到期前,后台主动预读并刷新高频访问的 DNS 记录"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:227
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:244
msgid "Quad9 Public DNS (149.112.112.112)"
@@ -663,7 +699,7 @@ msgstr "自定义规则列表"
msgid "Rules"
msgstr "规则列表"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:324
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:348
msgid "Save the cache locally and reload the cache dump on the next startup"
msgstr "保存缓存到本地文件,以供下次启动时重新载入使用"
@@ -679,7 +715,7 @@ msgstr "流媒体"
msgid "Streaming Media DNS server"
msgstr "流媒体 DNS 服务器"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:359
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:383
msgid "Support for local files, such as: file:///var/mosdns/example.txt"
msgstr "支持本地文件,例如:file:///var/mosdns/example.txt"
@@ -714,7 +750,7 @@ msgstr ""
"此功能通常在使用自建 DNS 服务器作为 远程 / 流媒体 DNS 上游时使用(需要上游服"
"务器的支持)"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:427
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:451
msgid ""
"This is the content of the file '/etc/mosdns/config_custom.yaml' from which "
"your MosDNS configuration will be generated. Only accepts configuration "
@@ -731,7 +767,7 @@ msgstr "火山引擎公共 DNS(180.184.1.1)"
msgid "TrafficRoute Public DNS (180.184.2.2)"
msgstr "火山引擎公共 DNS(180.184.2.2)"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:442
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:466
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:43
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:48
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js:67
@@ -797,7 +833,7 @@ msgstr ""
"启用 “自定义流媒体 DNS” 时,加入的域名始终使用 “流媒体 DNS 服务器” 进行解析"
"(每个域名一行,支持域名匹配规则)"
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:357
#: luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js:381
msgid ""
"When using custom rule sources, please use rule types supported by MosDNS "
"(domain list or AdGuardHome rules)."
+10
View File
@@ -22,6 +22,10 @@ get_config() {
config_get lazy_cache_ttl $1 lazy_cache_ttl 86400
config_get dump_file $1 dump_file 0
config_get dump_interval $1 dump_interval 3600
config_get prefetch $1 prefetch 0
config_get prefetch_before_expire $1 prefetch_before_expire 10
config_get prefetch_min_hits $1 prefetch_min_hits 3
config_get prefetch_scan_interval $1 prefetch_scan_interval 5
config_get enable_pipeline $1 enable_pipeline 0
config_get geo_auto_update $1 geo_auto_update 0
config_get geo_update_day_time $1 geo_update_day_time 2
@@ -232,6 +236,12 @@ generate_config() {
json_add_string "dump_file" "/etc/mosdns/cache.dump"
json_add_int "dump_interval" "$dump_interval"
}
[ "$prefetch" -eq 1 ] && {
json_add_boolean "prefetch" 1
json_add_int "prefetch_before_expire" "$prefetch_before_expire"
json_add_int "prefetch_min_hits" "$prefetch_min_hits"
json_add_int "prefetch_scan_interval" "$prefetch_scan_interval"
}
json_close_object
json_close_object
}
+1 -1
View File
@@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=mosdns
PKG_VERSION:=5.3.4
PKG_RELEASE:=15
PKG_RELEASE:=16
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/IrineSistiana/mosdns/tar.gz/v$(PKG_VERSION)?
@@ -0,0 +1,227 @@
From 819415303eb05bdf5b6dadf119f947645c9062cc Mon Sep 17 00:00:00 2001
From: sbwml <admin@cooluc.com>
Date: Sat, 22 Aug 2026 22:56:30 +0800
Subject: [PATCH] feat(cache): add proactive prefetch support
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
plugins:
- tag: lazy_cache
type: cache
args:
size: 1024
# 开启预读功能 (默认为 false)
prefetch: true
# 在 TTL 还剩 10 秒时尝试预读 (默认为 10)
prefetch_before_expire: 10
# 至少被命中 2 次才触发预读 (默认为 3)
prefetch_min_hits: 2
# 后台扫描周期,每 3 秒扫描一次 (默认为 5)
prefetch_scan_interval: 3
Signed-off-by: sbwml <admin@cooluc.com>
---
plugin/executable/cache/cache.go | 113 +++++++++++++++++++++++++++++--
plugin/executable/cache/utils.go | 2 +
2 files changed, 110 insertions(+), 5 deletions(-)
--- a/plugin/executable/cache/cache.go
+++ b/plugin/executable/cache/cache.go
@@ -27,6 +27,7 @@ import (
"io"
"net/http"
"os"
+ "reflect"
"strconv"
"sync"
"sync/atomic"
@@ -69,15 +70,22 @@ const (
var _ sequence.RecursiveExecutable = (*Cache)(nil)
type Args struct {
- Size int `yaml:"size"`
- LazyCacheTTL int `yaml:"lazy_cache_ttl"`
- DumpFile string `yaml:"dump_file"`
- DumpInterval int `yaml:"dump_interval"`
+ Size int `yaml:"size"`
+ LazyCacheTTL int `yaml:"lazy_cache_ttl"`
+ DumpFile string `yaml:"dump_file"`
+ DumpInterval int `yaml:"dump_interval"`
+ Prefetch bool `yaml:"prefetch"`
+ PrefetchBeforeExpire int `yaml:"prefetch_before_expire"`
+ PrefetchMinHits int `yaml:"prefetch_min_hits"`
+ PrefetchScanInterval int `yaml:"prefetch_scan_interval"`
}
func (a *Args) init() {
utils.SetDefaultUnsignNum(&a.Size, 1024)
utils.SetDefaultUnsignNum(&a.DumpInterval, 600)
+ utils.SetDefaultUnsignNum(&a.PrefetchBeforeExpire, 10)
+ utils.SetDefaultUnsignNum(&a.PrefetchMinHits, 3)
+ utils.SetDefaultUnsignNum(&a.PrefetchScanInterval, 5)
}
type Cache struct {
@@ -94,6 +102,11 @@ type Cache struct {
hitTotal prometheus.Counter
lazyHitTotal prometheus.Counter
size prometheus.GaugeFunc
+
+ prefetchTotal prometheus.Counter
+ prefetchFailTotal prometheus.Counter
+ capturedNext *sequence.ChainWalker
+ captureOnce sync.Once
}
func Init(bp *coremain.BP, args any) (any, error) {
@@ -160,6 +173,16 @@ func NewCache(args *Args, opts Opts) *Ca
Help: "The total number of queries that hit the expired cache",
ConstLabels: lb,
}),
+ prefetchTotal: prometheus.NewCounter(prometheus.CounterOpts{
+ Name: "prefetch_total",
+ Help: "The total number of successful proactive prefetch operations",
+ ConstLabels: lb,
+ }),
+ prefetchFailTotal: prometheus.NewCounter(prometheus.CounterOpts{
+ Name: "prefetch_fail_total",
+ Help: "The total number of failed proactive prefetch operations",
+ ConstLabels: lb,
+ }),
size: prometheus.NewGaugeFunc(prometheus.GaugeOpts{
Name: "size_current",
Help: "Current cache size in records",
@@ -173,12 +196,15 @@ func NewCache(args *Args, opts Opts) *Ca
p.logger.Error("failed to load cache dump", zap.Error(err))
}
p.startDumpLoop()
+ if p.args.Prefetch {
+ p.startPrefetchLoop()
+ }
return p
}
func (c *Cache) RegMetricsTo(r prometheus.Registerer) error {
- for _, collector := range [...]prometheus.Collector{c.queryTotal, c.hitTotal, c.lazyHitTotal, c.size} {
+ for _, collector := range [...]prometheus.Collector{c.queryTotal, c.hitTotal, c.lazyHitTotal, c.prefetchTotal, c.prefetchFailTotal, c.size} {
if err := r.Register(collector); err != nil {
return err
}
@@ -187,6 +213,15 @@ func (c *Cache) RegMetricsTo(r prometheu
}
func (c *Cache) Exec(ctx context.Context, qCtx *query_context.Context, next sequence.ChainWalker) error {
+ c.captureOnce.Do(func() {
+ // This implementation assumes the cache plugin is invoked from a single fixed position in the sequence.
+ nextCopy := next
+ c.capturedNext = &nextCopy
+ })
+ if c.capturedNext != nil && !reflect.DeepEqual(next, *c.capturedNext) {
+ c.logger.Warn("cache plugin Exec called with a different next chain than first time")
+ }
+
c.queryTotal.Inc()
q := qCtx.Q()
@@ -205,6 +240,7 @@ func (c *Cache) Exec(ctx context.Context
cachedResp.Id = q.Id // change msg id
qCtx.SetResponse(cachedResp)
if v, _, ok := c.backend.Get(key(msgKey)); ok && v != nil {
+ v.hitCount.Add(1)
ttl := int(v.expirationTime.Sub(v.storedTime).Seconds())
remainingTtl := int(v.expirationTime.Sub(time.Now()).Seconds())
if remainingTtl < 0 {
@@ -255,6 +291,73 @@ func (c *Cache) doLazyUpdate(msgKey stri
c.lazyUpdateSF.DoChan(msgKey, lazyUpdateFunc) // DoChan won't block this goroutine
}
+func (c *Cache) startPrefetchLoop() {
+ go func() {
+ ticker := time.NewTicker(time.Duration(c.args.PrefetchScanInterval) * time.Second)
+ defer ticker.Stop()
+ for {
+ select {
+ case <-ticker.C:
+ if c.capturedNext == nil {
+ continue
+ }
+ now := time.Now()
+ _ = c.backend.Range(func(k key, v *item, cacheExpirationTime time.Time) error {
+ remainingTTL := int(v.expirationTime.Sub(now).Seconds())
+ if remainingTTL >= 0 && remainingTTL < c.args.PrefetchBeforeExpire && v.hitCount.Load() >= uint32(c.args.PrefetchMinHits) {
+ c.doPrefetch(string(k), v, remainingTTL)
+ }
+ return nil
+ })
+ case <-c.closeNotify:
+ return
+ }
+ }
+ }()
+}
+
+func (c *Cache) doPrefetch(msgKey string, v *item, remainingTTL int) {
+ prefetchFunc := func() (any, error) {
+ defer c.lazyUpdateSF.Forget(msgKey)
+
+ req := new(dns.Msg)
+ req.SetQuestion(v.resp.Question[0].Name, v.resp.Question[0].Qtype)
+ req.Id = dns.Id()
+ req.RecursionDesired = true
+ newQCtx := query_context.NewContext(req)
+
+ qname := v.resp.Question[0].Name
+ hitCount := v.hitCount.Load()
+
+ c.logger.Debug("start proactive prefetch",
+ zap.String("qname", qname),
+ zap.Uint32("hit_count", hitCount),
+ zap.Int("remaining_ttl", remainingTTL),
+ )
+ ctx, cancel := context.WithTimeout(context.Background(), defaultLazyUpdateTimeout)
+ defer cancel()
+
+ err := c.capturedNext.ExecNext(ctx, newQCtx)
+ if err != nil {
+ c.logger.Warn("failed to proactive prefetch", zap.String("qname", qname), zap.Error(err))
+ c.prefetchFailTotal.Inc()
+ return nil, err
+ }
+
+ r := newQCtx.R()
+ if r != nil {
+ if saveRespToCache(msgKey, r, c.backend, c.args.LazyCacheTTL) {
+ v.hitCount.Store(0)
+ c.prefetchTotal.Inc()
+ c.updatedKey.Add(1)
+ }
+ }
+ c.logger.Debug("proactive prefetch updated", zap.String("qname", qname), newQCtx.InfoField())
+ return nil, nil
+ }
+ c.lazyUpdateSF.DoChan(msgKey, prefetchFunc)
+}
+
func (c *Cache) Close() error {
if err := c.dumpCache(); err != nil {
c.logger.Error("failed to dump cache", zap.Error(err))
--- a/plugin/executable/cache/utils.go
+++ b/plugin/executable/cache/utils.go
@@ -21,6 +21,7 @@ package cache
import (
"hash/maphash"
+ "sync/atomic"
"time"
"github.com/IrineSistiana/mosdns/v5/pkg/cache"
@@ -78,6 +79,7 @@ type item struct {
resp *dns.Msg
storedTime time.Time
expirationTime time.Time
+ hitCount atomic.Uint32
}
func copyNoOpt(m *dns.Msg) *dns.Msg {