diff --git a/dockerd/Config.in b/dockerd/Config.in index a9cf1f4c..a5a8b20c 100644 --- a/dockerd/Config.in +++ b/dockerd/Config.in @@ -15,6 +15,7 @@ config DOCKER_CGROUP_OPTIONS select KERNEL_CGROUP_FREEZER select KERNEL_NET_CLS_CGROUP select KERNEL_CGROUP_NET_PRIO + select PACKAGE_cgroupfs-mount help Selects kernel options to enable CGroups V1. diff --git a/dockerd/Makefile b/dockerd/Makefile index b3c17920..525c01b9 100644 --- a/dockerd/Makefile +++ b/dockerd/Makefile @@ -1,8 +1,9 @@ include $(TOPDIR)/rules.mk PKG_NAME:=dockerd +PKG_FLAGS:=hold PKG_VERSION:=27.3.1 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_LICENSE:=Apache-2.0 PKG_LICENSE_FILES:=LICENSE @@ -34,6 +35,7 @@ define Package/dockerd TITLE:=Docker Community Edition Daemon URL:=https://www.docker.com/ DEPENDS:=$(GO_ARCH_DEPENDS) \ + +jsonfilter \ +ca-certificates \ +containerd \ +iptables \ @@ -160,10 +162,19 @@ define Package/dockerd/install $(INSTALL_DIR) $(1)/etc/config $(INSTALL_CONF) ./files/etc/config/dockerd $(1)/etc/config/dockerd - # Must be after systcl 11-br-netfilter.conf from kmod-br-netfilter - $(INSTALL_DIR) $(1)/etc/sysctl.d - $(INSTALL_DATA) ./files/etc/sysctl.d/sysctl-br-netfilter-ip.conf \ - $(1)/etc/sysctl.d/12-br-netfilter-ip.conf + $(INSTALL_DIR) $(1)/etc/hotplug.d/net + $(INSTALL_DATA) ./files/etc/hotplug.d/net/br-netfilter \ + $(1)/etc/hotplug.d/net/10-docker-br-netfilter + + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_DATA) ./files/etc/uci-defaults/16_docker-netifd-migrate2 \ + $(1)/etc/uci-defaults/16_docker-netifd-migrate2 + $(INSTALL_DATA) ./files/etc/uci-defaults/17_docker-fw4 \ + $(1)/etc/uci-defaults/17_docker-fw4 + + $(INSTALL_DIR) $(1)/lib/fstab.d + $(INSTALL_DATA) ./files/lib/fstab.d/dockerd.sh $(1)/lib/fstab.d/dockerd.sh + endef define Package/dockerd/postinst diff --git a/dockerd/files/dockerd.init b/dockerd/files/dockerd.init index ec83ec5b..309fdd70 100755 --- a/dockerd/files/dockerd.init +++ b/dockerd/files/dockerd.init @@ -3,8 +3,8 @@ USE_PROCD=1 START=99 -extra_command "uciadd" " Add docker bridge configuration to network and firewall uci config" -extra_command "ucidel" " Delete docker bridge configuration from network and firewall uci config" +extra_command "uciadd" " Add docker bridge configuration to firewall uci config" +extra_command "ucidel" " Delete docker bridge configuration from firewall uci config" DOCKER_CONF_DIR="/tmp/dockerd" DOCKERD_CONF="${DOCKER_CONF_DIR}/daemon.json" @@ -17,94 +17,85 @@ json_add_array_string() { json_add_string "" "${1}" } -find_network_device() { - local device="${1}" - local device_section="" - - check_device() { - local cfg="${1}" - local device="${2}" - - local type name - config_get type "${cfg}" type - config_get name "${cfg}" name - - [ "${type}" = "bridge" ] && [ "${name}" = "${device}" ] \ - && device_section="${cfg}" - } - - config_load network - config_foreach check_device device "${device}" - - echo "${device_section}" -} - -boot() { - uciadd - rc_procd start_service -} - uciadd() { local iface="${1}" local device="${2}" local zone="${3}" - [ -z "${iface}" ] && { - iface="docker" + [ -z "${device}" ] && { device="docker0" zone="docker" } - /etc/init.d/dockerd running && { - echo "Please stop dockerd service first" - exit 0 - } - - # Add network interface - if ! uci_quiet get network.${iface}; then - logger -t "dockerd-init" -p notice "Adding interface '${iface}' to network config" - uci_quiet add network interface - uci_quiet rename network.@interface[-1]="${iface}" - uci_quiet set network.@interface[-1].device="${device}" - uci_quiet set network.@interface[-1].proto="none" - uci_quiet set network.@interface[-1].auto="0" - uci_quiet commit network - fi - - # Add docker bridge device - if [ "$(find_network_device "$device")" = "" ]; then - logger -t "dockerd-init" -p notice "Adding bridge device '${device}' to network config" - uci_quiet add network device - uci_quiet set network.@device[-1].type="bridge" - uci_quiet set network.@device[-1].name="${device}" - uci_quiet commit network - else - logger -t "dockerd-init" -p notice "Bridge device '${device}' already defined in network config" - fi - # Add firewall zone if ! uci_quiet get firewall.${zone}; then logger -t "dockerd-init" -p notice "Adding firewall zone '${zone}' to firewall config" uci_quiet add firewall zone uci_quiet rename firewall.@zone[-1]="${zone}" + uci_quiet set firewall.@zone[-1].name="${zone}" uci_quiet set firewall.@zone[-1].input="ACCEPT" uci_quiet set firewall.@zone[-1].output="ACCEPT" uci_quiet set firewall.@zone[-1].forward="ACCEPT" - uci_quiet set firewall.@zone[-1].name="${zone}" uci_quiet set firewall.dockerd=forwarding uci_quiet set firewall.@forwarding[-1].src="${zone}" uci_quiet set firewall.@forwarding[-1].dest='wan' uci_quiet commit firewall fi - # Add interface to firewall zone + # Add device to firewall zone if uci_quiet get firewall.${zone}; then - uci_quiet del_list firewall.${zone}.network="${iface}" - uci_quiet add_list firewall.${zone}.network="${iface}" + uci_quiet del_list firewall.${zone}.device="${device}" + if [ docker0 = "$device" ]; then + uci_quiet del_list firewall.${zone}.subnet="172.16.0.0/12" + uci_quiet add_list firewall.${zone}.subnet="172.16.0.0/12" + else + uci_quiet add_list firewall.${zone}.device="${device}" + fi uci_quiet commit firewall fi - reload_config + # Add forwarding rules + local forwarding_section + check_forwarding() { + local cfg="${1}" + local srcm="${2}" + local destm="${3}" + + local src dest + config_get src "${cfg}" src + config_get dest "${cfg}" dest + + [[ "${src}" = "${srcm}" && "${dest}" = "${destm}" ]] \ + && forwarding_section="${cfg}" + } + + config_load firewall + forwarding_section="" + config_foreach check_forwarding forwarding ${zone} wan + [[ -n "${forwarding_section}" ]] || { + uci_quiet set firewall.${zone}_to_wan=forwarding + uci_quiet set firewall.${zone}_to_wan.src=${zone} + uci_quiet set firewall.${zone}_to_wan.dest=wan + } + + forwarding_section="" + config_foreach check_forwarding forwarding ${zone} lan + [[ -n "${forwarding_section}" ]] || { + uci_quiet set firewall.${zone}_to_lan=forwarding + uci_quiet set firewall.${zone}_to_lan.src=${zone} + uci_quiet set firewall.${zone}_to_lan.dest=lan + } + + forwarding_section="" + config_foreach check_forwarding forwarding lan ${zone} + [[ -n "${forwarding_section}" ]] || { + uci_quiet set firewall.lan_to_${zone}=forwarding + uci_quiet set firewall.lan_to_${zone}.src=lan + uci_quiet set firewall.lan_to_${zone}.dest=${zone} + } + uci_quiet commit firewall + + /etc/init.d/firewall reload } ucidel() { @@ -112,44 +103,28 @@ ucidel() { local device="${2}" local zone="${3}" - [ -z "${iface}" ] && { - iface="docker" + [ -z "${device}" ] && { device="docker0" zone="docker" } - /etc/init.d/dockerd running && { - echo "Please stop dockerd service first" - exit 0 - } - - # Remove network device - if uci_quiet delete network.$(find_network_device "${device}"); then - logger -t "dockerd-init" -p notice "Deleting bridge device '${device}' from network config" - uci_quiet commit network - fi - - # Remove network interface - if uci_quiet get network.${iface}; then - logger -t "dockerd-init" -p notice "Deleting interface '${iface}' from network config" - uci_quiet delete network.${iface} - uci_quiet commit network - fi - # Remove interface from firewall zone if uci_quiet get firewall.${zone}; then - logger -t "dockerd-init" -p notice "Deleting network interface '${iface}' in zone '${zone}' from firewall config" - uci_quiet del_list firewall.${zone}.network="${iface}" + logger -t "dockerd-init" -p notice "Deleting network device '${device}' in zone '${zone}' from firewall config" + uci_quiet del_list firewall.${zone}.device="${device}" uci_quiet commit firewall # Remove Firewall zone if network is empty - if ! uci_quiet get firewall.${zone}.network; then + if ! uci_quiet get firewall.${zone}.device; then logger -t "dockerd-init" -p notice "Deleting firewall zone '${zone}' from firewall config" uci_quiet delete firewall.${zone} + uci_quiet delete firewall.${zone}_to_wan + uci_quiet delete firewall.${zone}_to_lan + uci_quiet delete firewall.lan_to_${zone} fi uci_quiet commit firewall fi - reload_config + /etc/init.d/firewall reload } process_config() { @@ -174,7 +149,7 @@ process_config() { config_get data_root globals data_root "/opt/docker/" config_get log_level globals log_level "warn" - config_get_bool iptables globals iptables "1" + config_get_bool iptables globals iptables "0" config_get_bool ip6tables globals ip6tables "0" # Don't add these options by default @@ -193,6 +168,7 @@ process_config() { config_get https_proxy proxies https_proxy "${https_proxy}" config_get no_proxy proxies no_proxy "${no_proxy}" config_get storage_driver globals storage_driver "" + config_get max_concurrent_downloads globals max_concurrent_downloads "" . /usr/share/libubox/jshn.sh json_init @@ -223,6 +199,14 @@ process_config() { json_close_object fi [ -z "${storage_driver}" ] || json_add_string "storage-driver" "${storage_driver}" + + [ "${max_concurrent_downloads:-0}" -eq "0" ] || json_add_int "max-concurrent-downloads" "${max_concurrent_downloads}" + json_add_string "log-driver" "json-file" + json_add_object "log-opts" + json_add_string "max-size" "50m" + json_add_string "max-file" "2" + json_close_object + json_dump > "${DOCKERD_CONF}" [ "${iptables}" -eq "1" ] && config_foreach iptables_add_blocking_rule firewall @@ -245,6 +229,14 @@ start_service() { } reload_service() { + if [ -f "${DOCKERD_CONF}" -a -f /etc/config/dockerd ]; then + local oldroot=`jsonfilter -i "${DOCKERD_CONF}" -e @[\"data-root\"]` + local newroot=`uci get dockerd.globals.data_root` + if [ "$oldroot" != "$newroot" ]; then + restart + return 0 + fi + fi process_config procd_send_signal dockerd } diff --git a/dockerd/files/etc/config/dockerd b/dockerd/files/etc/config/dockerd index ab230d5b..6394175b 100644 --- a/dockerd/files/etc/config/dockerd +++ b/dockerd/files/etc/config/dockerd @@ -10,7 +10,7 @@ config globals 'globals' option data_root '/opt/docker/' # option log_driver 'local' option log_level 'warn' - option iptables '1' + option iptables '0' # list hosts 'unix:///var/run/docker.sock' # option bip '172.18.0.1/24' # option fixed_cidr '172.17.0.0/16' @@ -20,6 +20,7 @@ config globals 'globals' # list dns '172.17.0.1' # list registry_mirrors 'https://' # list registry_mirrors 'https://hub.docker.com' +# option max_concurrent_downloads '2' # If your organization uses a proxy server to connect to the internet, you may need to configure the proxy. # See https://docs.docker.com/engine/daemon/proxy/ for more details diff --git a/dockerd/files/etc/hotplug.d/net/br-netfilter b/dockerd/files/etc/hotplug.d/net/br-netfilter new file mode 100644 index 00000000..4cb9dc7e --- /dev/null +++ b/dockerd/files/etc/hotplug.d/net/br-netfilter @@ -0,0 +1,12 @@ +#!/bin/sh + +if [ "$ACTION" = add -a "x$DEVTYPE" = xbridge ]; then + if [ "$DEVICENAME" = "docker0" ] || echo "$DEVICENAME" | grep -qE '^br-[0-9a-f]{12}$'; then + if [ "$(uci -q get dockerd.globals.iptables)" = "1" ]; then + echo "1" >/sys$DEVPATH/bridge/nf_call_iptables + fi + if [ "$(uci -q get dockerd.globals.ip6tables)" = "1" ]; then + echo "1" >/sys$DEVPATH/bridge/nf_call_ip6tables + fi + fi +fi diff --git a/dockerd/files/etc/sysctl.d/sysctl-br-netfilter-ip.conf b/dockerd/files/etc/sysctl.d/sysctl-br-netfilter-ip.conf deleted file mode 100644 index 9522d9e9..00000000 --- a/dockerd/files/etc/sysctl.d/sysctl-br-netfilter-ip.conf +++ /dev/null @@ -1,7 +0,0 @@ -# Do not edit, changes to this file will be lost on upgrades -# /etc/sysctl.conf can be used to customize sysctl settings - -# enable bridge firewalling for docker -# net.bridge.bridge-nf-call-ip6tables=1 -# net.bridge.bridge-nf-call-iptables=1 - diff --git a/dockerd/files/etc/uci-defaults/16_docker-netifd-migrate2 b/dockerd/files/etc/uci-defaults/16_docker-netifd-migrate2 new file mode 100644 index 00000000..52960d21 --- /dev/null +++ b/dockerd/files/etc/uci-defaults/16_docker-netifd-migrate2 @@ -0,0 +1,13 @@ +#!/bin/sh + +uci -q set dockerd.globals.iptables=0 + +uci -q delete firewall.docker.network + +DOCKER0_DEVICE=`uci show network | grep -E "^network\\.@device\\[\\d+\\]\\.name='docker0'" | head -n1 | head -c -16` + +if [ -n "$DOCKER0_DEVICE" ]; then + uci delete "$DOCKER0_DEVICE" +fi +uci -q delete network.docker +uci commit diff --git a/dockerd/files/etc/uci-defaults/17_docker-fw4 b/dockerd/files/etc/uci-defaults/17_docker-fw4 new file mode 100644 index 00000000..a3a63f51 --- /dev/null +++ b/dockerd/files/etc/uci-defaults/17_docker-fw4 @@ -0,0 +1,5 @@ +#!/bin/sh + +/etc/init.d/dockerd uciadd + +exit 0 diff --git a/dockerd/files/lib/fstab.d/dockerd.sh b/dockerd/files/lib/fstab.d/dockerd.sh new file mode 100644 index 00000000..5258a689 --- /dev/null +++ b/dockerd/files/lib/fstab.d/dockerd.sh @@ -0,0 +1,3 @@ +if /etc/init.d/dockerd enabled && [ -f /etc/config/dockerd ]; then + fstab_add_essential_mountpoint "$(uci -q get dockerd.globals.data_root)" +fi diff --git a/dockerd/git-short-commit.sh b/dockerd/git-short-commit.sh index 6354b9e6..650ab8c8 100755 --- a/dockerd/git-short-commit.sh +++ b/dockerd/git-short-commit.sh @@ -39,7 +39,7 @@ git init --quiet "${GIT_DIR}" if git fetch --depth 1 origin "${GIT_REF}"; then git checkout --detach FETCH_HEAD -- - git rev-parse --short=7 HEAD + git rev-parse --short HEAD break fi diff --git a/luci-app-arcadia/Makefile b/luci-app-arcadia/Makefile index a361d677..8c2aed98 100644 --- a/luci-app-arcadia/Makefile +++ b/luci-app-arcadia/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.0.0-20250610 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for arcadia LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd define Package/luci-app-arcadia/conffiles /etc/config/arcadia diff --git a/luci-app-chinesesubfinder/Makefile b/luci-app-chinesesubfinder/Makefile index 50da8473..970e41de 100644 --- a/luci-app-chinesesubfinder/Makefile +++ b/luci-app-chinesesubfinder/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.0.3-20240822 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for ChineseSubFinder LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd define Package/luci-app-chinesesubfinder/conffiles /etc/config/chinesesubfinder diff --git a/luci-app-codeserver/Makefile b/luci-app-codeserver/Makefile index 625220e4..f962c5c1 100644 --- a/luci-app-codeserver/Makefile +++ b/luci-app-codeserver/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.0.2-20251011 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for CodeServer LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd define Package/luci-app-codeserver/conffiles /etc/config/codeserver diff --git a/luci-app-demon/Makefile b/luci-app-demon/Makefile index d75f01b9..6a214280 100644 --- a/luci-app-demon/Makefile +++ b/luci-app-demon/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.2.0-20250625 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for demon LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd define Package/luci-app-demon/conffiles /etc/config/demon diff --git a/luci-app-docker/Makefile b/luci-app-docker/Makefile index d688caa7..d4f8c229 100644 --- a/luci-app-docker/Makefile +++ b/luci-app-docker/Makefile @@ -7,10 +7,10 @@ include $(TOPDIR)/rules.mk LUCI_TITLE:=Luci for Docker-CE -LUCI_DEPENDS:=+luci-compat +docker +dockerd +dockerd +e2fsprogs +fdisk +LUCI_DEPENDS:=+luci-compat +docker +dockerd +e2fsprogs +fdisk LUCI_PKGARCH:=all PKG_VERSION:=1 -PKG_RELEASE:=1 +PKG_RELEASE:=2 include $(TOPDIR)/feeds/luci/luci.mk diff --git a/luci-app-dockerman/Makefile b/luci-app-dockerman/Makefile index 4f134266..2fd75917 100644 --- a/luci-app-dockerman/Makefile +++ b/luci-app-dockerman/Makefile @@ -7,7 +7,7 @@ LUCI_DEPENDS:=@(aarch64||arm||x86_64) \ +luci-base \ +luci-compat \ +luci-lib-docker \ - +docker +dockerd \ + +docker \ +ttyd \ +dockerd \ +docker-compose @@ -17,7 +17,7 @@ PKG_MAINTAINER:=lisaac \ Florian Eckert PKG_VERSION:=0.5.13.20250109 -PKG_RELEASE:=1 +PKG_RELEASE:=2 include $(TOPDIR)/feeds/luci/luci.mk diff --git a/luci-app-dpanel/Makefile b/luci-app-dpanel/Makefile index c02418af..f34fe9c7 100644 --- a/luci-app-dpanel/Makefile +++ b/luci-app-dpanel/Makefile @@ -4,11 +4,11 @@ include $(TOPDIR)/rules.mk # Updated: 2025-10-09 PKG_VERSION:=1.0.0-20251009 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for DPanel LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +zoneinfo-asia +docker +dockerd +luci-lib-taskd +luci-lib-docker +LUCI_DEPENDS:=+lsblk +zoneinfo-asia +docker +luci-lib-taskd +luci-lib-docker define Package/luci-app-dpanel/conffiles /etc/config/dpanel diff --git a/luci-app-drawio/Makefile b/luci-app-drawio/Makefile index cfe94f4e..3ec4b12b 100644 --- a/luci-app-drawio/Makefile +++ b/luci-app-drawio/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.0.0-20240822 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for DrawIO LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +luci-lib-docker +docker-compose +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd +luci-lib-docker +docker-compose define Package/luci-app-drawio/conffiles /etc/config/drawio diff --git a/luci-app-emby/Makefile b/luci-app-emby/Makefile index 5aced329..b75cc8d3 100644 --- a/luci-app-emby/Makefile +++ b/luci-app-emby/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.0.3-20240822 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for Emby LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd define Package/luci-app-emby/conffiles /etc/config/emby diff --git a/luci-app-excalidraw/Makefile b/luci-app-excalidraw/Makefile index f5ff20e8..82aed40f 100644 --- a/luci-app-excalidraw/Makefile +++ b/luci-app-excalidraw/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.0.0-20240822 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for Excalidraw LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +luci-lib-docker +docker-compose +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd +luci-lib-docker +docker-compose define Package/luci-app-excalidraw/conffiles /etc/config/excalidraw diff --git a/luci-app-feishuvpn/Makefile b/luci-app-feishuvpn/Makefile index dad7541f..c289bb7b 100644 --- a/luci-app-feishuvpn/Makefile +++ b/luci-app-feishuvpn/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.0.2-20240822 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for FeiShuVpn LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +luci-lib-docker +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd +luci-lib-docker define Package/luci-app-feishuvpn/conffiles /etc/config/feishuvpn diff --git a/luci-app-gogs/Makefile b/luci-app-gogs/Makefile index f40923e8..7f8a9a1e 100644 --- a/luci-app-gogs/Makefile +++ b/luci-app-gogs/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.0.3-20240822 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for Gogs LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd define Package/luci-app-gogs/conffiles /etc/config/gogs diff --git a/luci-app-heimdall/Makefile b/luci-app-heimdall/Makefile index b7486edd..e4f732de 100644 --- a/luci-app-heimdall/Makefile +++ b/luci-app-heimdall/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.1.2-20240822 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for heimdall LUCI_PKGARCH:=all -LUCI_DEPENDS:=+docker +dockerd +luci-lib-taskd +LUCI_DEPENDS:=+docker +luci-lib-taskd define Package/luci-app-heimdall/conffiles /etc/config/heimdall diff --git a/luci-app-homeassistant/Makefile b/luci-app-homeassistant/Makefile index 86619c22..78940b59 100644 --- a/luci-app-homeassistant/Makefile +++ b/luci-app-homeassistant/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.1.4-20250321 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for homeassistant LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd define Package/luci-app-homeassistant/conffiles /etc/config/homeassistant diff --git a/luci-app-htreader/Makefile b/luci-app-htreader/Makefile index a3ce14f1..3d1c50bd 100644 --- a/luci-app-htreader/Makefile +++ b/luci-app-htreader/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.0.2-20240822 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for HTReader LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +luci-lib-docker +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd +luci-lib-docker define Package/luci-app-htreader/conffiles /etc/config/htreader diff --git a/luci-app-immich/Makefile b/luci-app-immich/Makefile index 2e70a444..d4fb1ad7 100644 --- a/luci-app-immich/Makefile +++ b/luci-app-immich/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.0.2-20250321 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for Immich LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +luci-lib-docker +docker-compose +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd +luci-lib-docker +docker-compose define Package/luci-app-immich/conffiles /etc/config/immich diff --git a/luci-app-istoredup/Makefile b/luci-app-istoredup/Makefile index 5ef9f9f1..bf9d685c 100644 --- a/luci-app-istoredup/Makefile +++ b/luci-app-istoredup/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.1.7-20241211 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for istoredup LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +vmease +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd +vmease define Package/luci-app-istoredup/conffiles /etc/config/istoredup diff --git a/luci-app-istorego/Makefile b/luci-app-istorego/Makefile index 6b31d8fb..70cb8ec8 100644 --- a/luci-app-istorego/Makefile +++ b/luci-app-istorego/Makefile @@ -6,12 +6,12 @@ include $(TOPDIR)/rules.mk LUCI_TITLE:=LuCI support for istorego -LUCI_DEPENDS:=+docker +dockerd +luci-lib-taskd +LUCI_DEPENDS:=+docker +luci-lib-taskd LUCI_PKGARCH:=all PKG_VERSION:=0.0.3 # PKG_RELEASE MUST be empty for luci.mk -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_MINIFY_CSS:=0 LUCI_MINIFY_JS:=0 diff --git a/luci-app-istorepanel/Makefile b/luci-app-istorepanel/Makefile index 780f0733..9e35df54 100644 --- a/luci-app-istorepanel/Makefile +++ b/luci-app-istorepanel/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.0.6-20250406 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for 1Panel LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +zoneinfo-asia +docker +dockerd +luci-lib-taskd +luci-lib-docker +LUCI_DEPENDS:=+lsblk +zoneinfo-asia +docker +luci-lib-taskd +luci-lib-docker define Package/luci-app-istorepanel/conffiles /etc/config/istorepanel diff --git a/luci-app-ittools/Makefile b/luci-app-ittools/Makefile index 7639a389..efebfa21 100644 --- a/luci-app-ittools/Makefile +++ b/luci-app-ittools/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.0.4-20250321 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for ITTools LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +luci-lib-docker +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd +luci-lib-docker define Package/luci-app-ittools/conffiles /etc/config/ittools diff --git a/luci-app-jackett/Makefile b/luci-app-jackett/Makefile index e1ef72f0..e9811560 100644 --- a/luci-app-jackett/Makefile +++ b/luci-app-jackett/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.1.1-20240822 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for jackett LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd define Package/luci-app-jackett/conffiles /etc/config/jackett diff --git a/luci-app-jellyfin/Makefile b/luci-app-jellyfin/Makefile index 63f316c1..3aa3eea2 100644 --- a/luci-app-jellyfin/Makefile +++ b/luci-app-jellyfin/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.2.2-20250321 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for jellyfin LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd define Package/luci-app-jellyfin/conffiles /etc/config/jellyfin diff --git a/luci-app-lanraragi/Makefile b/luci-app-lanraragi/Makefile index bcf3f553..b717a3ea 100644 --- a/luci-app-lanraragi/Makefile +++ b/luci-app-lanraragi/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.0.1-20240822 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for LANraragi LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd define Package/luci-app-lanraragi/conffiles /etc/config/lanraragi diff --git a/luci-app-memos/Makefile b/luci-app-memos/Makefile index 353604af..75008688 100644 --- a/luci-app-memos/Makefile +++ b/luci-app-memos/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.0.2-20240822 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for Memos LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd define Package/luci-app-memos/conffiles /etc/config/memos diff --git a/luci-app-mfun/Makefile b/luci-app-mfun/Makefile index 63f19fa1..d240be3c 100644 --- a/luci-app-mfun/Makefile +++ b/luci-app-mfun/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=0.0.1 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for mfun LUCI_PKGARCH:=all -LUCI_DEPENDS:=+docker +dockerd +luci-lib-taskd +LUCI_DEPENDS:=+docker +luci-lib-taskd define Package/luci-app-mfun/conffiles /etc/config/mfun diff --git a/luci-app-mosdns/Makefile b/luci-app-mosdns/Makefile index 626cb5ce..3afab63a 100644 --- a/luci-app-mosdns/Makefile +++ b/luci-app-mosdns/Makefile @@ -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 diff --git a/luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js b/luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js index 8fd3eef7..d8f047c8 100644 --- a/luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js +++ b/luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/basic.js @@ -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') + ' ' + 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 = ' '; 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 */ diff --git a/luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/logs.js b/luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/logs.js index 48ba3d7f..98d4c2df 100644 --- a/luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/logs.js +++ b/luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/logs.js @@ -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 () { diff --git a/luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js b/luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js index ad6774c6..4f49aaa3 100644 --- a/luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js +++ b/luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/rules.js @@ -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, '' @@ -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, '' @@ -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, '' @@ -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, '' @@ -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, '' @@ -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, '' @@ -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, '' @@ -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, '' @@ -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))); diff --git a/luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js b/luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js index 2dd12dba..5cdb4877 100644 --- a/luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js +++ b/luci-app-mosdns/htdocs/luci-static/resources/view/mosdns/update.js @@ -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 + '
' + i.stdout), 'warn'); + ui.addNotification(null, E('p', res.stderr + '
' + 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(); } diff --git a/luci-app-mosdns/po/templates/mosdns.pot b/luci-app-mosdns/po/templates/mosdns.pot new file mode 100644 index 00000000..24e45c76 --- /dev/null +++ b/luci-app-mosdns/po/templates/mosdns.pot @@ -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 , 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 \n" +"Language-Team: LANGUAGE \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: https://www.cloudflare.com/ips-v4
IPv6 CIDR: https://www.cloudflare.com/ips-" +"v6" +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 "" diff --git a/luci-app-mosdns/po/zh_Hans/mosdns.po b/luci-app-mosdns/po/zh_Hans/mosdns.po index 9c47c71c..daf81c84 100644 --- a/luci-app-mosdns/po/zh_Hans/mosdns.po +++ b/luci-app-mosdns/po/zh_Hans/mosdns.po @@ -1,489 +1,812 @@ msgid "" msgstr "" -"Content-Type: text/plain; charset=UTF-8\n" "Project-Id-Version: PACKAGE VERSION\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-03-20 09:23+0800\n" +"PO-Revision-Date: 2026-03-19 20:33+0800\n" +"Last-Translator: sbwml \n" +"Language-Team: Chinese\n" "Language: zh_Hans\n" "MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\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 "MosDNS" -msgid "MosDNS is a plugin-based DNS forwarder/traffic splitter." -msgstr "MosDNS 是一个插件化的 DNS 转发/分流器。" - -msgid "Basic Setting" -msgstr "基本设置" - -msgid "Basic Options" -msgstr "基本选项" - -msgid "Advanced Options" -msgstr "高级选项" - -msgid "Cloudflare Options" -msgstr "Cloudflare 选项" - -msgid "API Options" -msgstr "API 选项" - +#: 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 "未运行" -msgid "Collecting data..." -msgstr "获取数据中..." - -msgid "Enabled" -msgstr "启用" - -msgid "Listen Port" -msgstr "监听端口" - -msgid "Listen Address" -msgstr "监听地址" - -msgid "API Listen port" -msgstr "API 监听端口" - -msgid "Flush DNS Cache" -msgstr "刷新 DNS 缓存" - -msgid "Flushing DNS Cache will clear any IP addresses or DNS records from MosDNS cache." -msgstr "刷新 DNS 缓存会清空 MosDNS 所有 IP 地址和 DNS 解析缓存。" - +#: htdocs/luci-static/resources/view/mosdns/basic.js:95 msgid "Flushing DNS Cache Success." msgstr "刷新 DNS 缓存成功" +#: htdocs/luci-static/resources/view/mosdns/basic.js:97 msgid "Flushing DNS Cache Failed, Please check if MosDNS is running." msgstr "刷新 DNS 缓存失败,请检查 MosDNS 状态是否在运行中。" -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 "将解析结果与 Cloudflare IP 范围进行匹配,当匹配成功时,使用 “自选 IP” 作为解析结果(实验性功能)" +#: htdocs/luci-static/resources/view/mosdns/basic.js:111 +msgid "MosDNS is a plugin-based DNS forwarder/traffic splitter." +msgstr "MosDNS 是一个插件化的 DNS 转发/分流器。" -msgid "Custom IP" -msgstr "自选 IP" +#: htdocs/luci-static/resources/view/mosdns/basic.js:133 +msgid "Collecting data..." +msgstr "获取数据中..." -msgid "Cloudflare IP Ranges" -msgstr "Cloudflare IP 范围" +#: htdocs/luci-static/resources/view/mosdns/basic.js:139 +msgid "Basic Options" +msgstr "基本选项" -msgid "Log Level" -msgstr "日志等级" +#: htdocs/luci-static/resources/view/mosdns/basic.js:140 +msgid "Advanced Options" +msgstr "高级选项" -msgid "DNS Forward" -msgstr "DNS 转发" +#: htdocs/luci-static/resources/view/mosdns/basic.js:141 +msgid "Cloudflare Options" +msgstr "Cloudflare 选项" -msgid "Forward Dnsmasq Domain Name resolution requests to MosDNS" -msgstr "将 Dnsmasq 域名解析请求转发到 MosDNS 服务器" - -msgid "DNS redirect" -msgstr "DNS 重定向" - -msgid "Force redirect all local DNS queries to MosDNS, a.k.a. DNS Hijacking" -msgstr "强制将所有本地 DNS 查询重定向到 MosDNS,即 DNS 劫持。" - -msgid "Disable RR Type 65 (HTTPS/SVCB)" -msgstr "禁用 RR Type 65 (HTTPS/SVCB)" - -msgid "Block DNS RR Type 65 records (HTTPS/SVCB, used for HTTP/3, ECH, etc.), force using only A/AAAA records." -msgstr "屏蔽 DNS 类型 65 记录(HTTPS/SVCB,用于 HTTP/3、ECH 等),强制仅使用 A/AAAA 解析。" - -msgid "Enable DNS ADblock" -msgstr "启用 DNS 广告过滤" - -msgid "ADblock Source" -msgstr "广告过滤规则来源" - -msgid "When using custom rule sources, please use rule types supported by MosDNS (domain lists)." -msgstr "使用自定义规则来源时,请使用 MosDNS 支持的规则类型(域名列表)" - -msgid "Support for local files, such as: file:///var/mosdns/example.txt" -msgstr "支持本地文件,例如:file:///var/mosdns/example.txt" - -msgid "Configuration Editor" -msgstr "配置编辑器" - -msgid "Edit the MosDNS custom configuration file." -msgstr "编辑 MosDNS 自定义配置文件。" - -msgid "Configuration have been saved." -msgstr "配置已保存。" - -msgid "This is the content of the file '/etc/mosdns/config_custom.yaml' from which your MosDNS configuration will be generated. Only accepts configuration content in yaml format." -msgstr "这是文件 “/etc/mosdns/config_custom.yaml” 的内容,您的 MosDNS 配置将从此文件生成。仅接受 yaml 格式的配置内容。" - -msgid "Geodata Update" -msgstr "更新数据库" - -msgid "Update GeoIP & GeoSite databases" -msgstr "更新广告规则、GeoIP & GeoSite 数据库" - -msgid "Automatically update GeoIP and GeoSite databases as well as ad filtering rules through scheduled tasks." -msgstr "通过定时任务自动更新 GeoIP 和 GeoSite 数据库以及广告过滤规则。" - -msgid "Update Time" -msgstr "更新时间" - -msgid "Update Cycle" -msgstr "更新周期" - -msgid "Every Day" -msgstr "每天" - -msgid "Every Monday" -msgstr "每周一" - -msgid "Every Tuesday" -msgstr "每周二" - -msgid "Every Wednesday" -msgstr "每周三" - -msgid "Every Thursday" -msgstr "每周四" - -msgid "Every Friday" -msgstr "每周五" - -msgid "Every Saturday" -msgstr "每周六" - -msgid "Every Sunday" -msgstr "每周日" - -msgid "GeoIP Type" -msgstr "GeoIP 类型" - -msgid "Little" -msgstr "轻量" - -msgid "Little: only include Mainland China and Private IP addresses." -msgstr "轻量:仅包含中国大陆和私有 IP 地址。" - -msgid "Full" -msgstr "全量" - -msgid "Full: includes all Countries and Private IP addresses." -msgstr "全量:包含所有国家和私有 IP 地址。" - -msgid "GitHub Proxy" -msgstr "GitHub 代理" - -msgid "Update data files with GitHub Proxy, leave blank to disable proxy downloads." -msgstr "通过 GitHub 代理更新数据文件,留空则禁用代理下载。" - -msgid "Database Update" -msgstr "数据库更新" - -msgid "Check And Update GeoData." -msgstr "检查并更新 GeoData 数据库。" - -msgid "Check And Update" -msgstr "检查并更新" - -msgid "Enable Auto Database Update" -msgstr "启用自动更新" - -msgid "Update success" -msgstr "更新成功" - -msgid "Update failed, Please check the network status" -msgstr "更新失败,请检查网络状态" - -msgid "Config File" -msgstr "配置文件" - -msgid "Default Config" -msgstr "内置预设" - -msgid "Custom Config" -msgstr "自定义" - -msgid "Log File" -msgstr "日志文件" - -msgid "China DNS prefer IPv4" -msgstr "国内 DNS 首选 IPv4" - -msgid "IPv4 is preferred for China DNS resolution of dual-stack addresses, and is not affected when the destination is IPv6 only" -msgstr "国内 DNS 解析双栈地址时首选 IPv4,目标仅 IPv6 时不受影响" - -msgid "Remote DNS prefer IPv4" -msgstr "远程 DNS 首选 IPv4" - -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 "远程 / 流媒体 DNS 解析双栈地址时首选 IPv4,目标仅 IPv6 时不受影响" - -msgid "Custom China DNS" -msgstr "自定义国内 DNS" - -msgid "Follow WAN interface DNS if not enabled" -msgstr "不启用则使用 WAN 接口 DNS" - -msgid "Apple domains optimization" -msgstr "Apple 域名解析优化" - -msgid "For Apple domains equipped with Chinese mainland CDN, always responsive to Chinese CDN IP addresses" -msgstr "配备中国大陆 CDN 的 Apple 域名,始终应答中国大陆 CDN 地址" - -msgid "China DNS server" -msgstr "国内 DNS 服务器" - -msgid "Remote DNS server" -msgstr "远程 DNS 服务器" - -msgid "Bootstrap DNS servers" -msgstr "Bootstrap DNS 服务器" - -msgid "Bootstrap DNS servers are used to resolve IP addresses of the DoH/DoT resolvers you specify as upstreams" -msgstr "Bootstrap DNS 服务器用于解析您指定为上游的 DoH / DoT 解析器的 IP 地址" - -msgid "Tencent Public DNS (119.29.29.29)" -msgstr "腾讯公共 DNS(119.29.29.29)" - -msgid "Tencent Public DNS (119.28.28.28)" -msgstr "腾讯公共 DNS(119.28.28.28)" - -msgid "Aliyun Public DNS (223.5.5.5)" -msgstr "阿里云公共 DNS(223.5.5.5)" - -msgid "Aliyun Public DNS (223.6.6.6)" -msgstr "阿里云公共 DNS(223.6.6.6)" - -msgid "TrafficRoute Public DNS (180.184.1.1)" -msgstr "火山引擎公共 DNS(180.184.1.1)" - -msgid "TrafficRoute Public DNS (180.184.2.2)" -msgstr "火山引擎公共 DNS(180.184.2.2)" - -msgid "Xinfeng Public DNS (114.114.114.114)" -msgstr "信风公共 DNS(114.114.114.114)" - -msgid "Xinfeng Public DNS (114.114.115.115)" -msgstr "信风公共 DNS(114.114.115.115)" - -msgid "Baidu Public DNS (180.76.76.76)" -msgstr "百度公共 DNS(180.76.76.76)" - -msgid "Tencent Public DNS (DNS over HTTPS)" -msgstr "腾讯公共 DNS(DNS over HTTPS)" - -msgid "Aliyun Public DNS (DNS over QUIC)" -msgstr "阿里云公共 DNS(DNS over QUIC)" - -msgid "Aliyun Public DNS (DNS over HTTPS)" -msgstr "阿里云公共 DNS(DNS over HTTPS)" - -msgid "Aliyun Public DNS (DNS over HTTP/3)" -msgstr "阿里云公共 DNS(DNS over HTTP/3)" - -msgid "360 Public DNS (DNS over HTTPS)" -msgstr "360 安全 DNS(DNS over HTTPS)" - -msgid "CloudFlare Public DNS (1.1.1.1)" -msgstr "CloudFlare 公共 DNS(1.1.1.1)" - -msgid "CloudFlare Public DNS (1.0.0.1)" -msgstr "CloudFlare 公共 DNS(1.0.0.1)" - -msgid "Google Public DNS (8.8.8.8)" -msgstr "谷歌公共 DNS(8.8.8.8)" - -msgid "Google Public DNS (8.8.4.4)" -msgstr "谷歌公共 DNS(8.8.4.4)" - -msgid "Quad9 Public DNS (9.9.9.9)" -msgstr "Quad9 公共 DNS(9.9.9.9)" - -msgid "Quad9 Public DNS (149.112.112.112)" -msgstr "Quad9 公共 DNS(149.112.112.112)" - -msgid "Cisco Public DNS (208.67.222.222)" -msgstr "思科公共 DNS(208.67.222.222)" - -msgid "Cisco Public DNS (208.67.220.220)" -msgstr "思科公共 DNS(208.67.220.220)" - -msgid "Concurrent" -msgstr "DNS 服务器并发数(默认 2)" - -msgid "DNS query request concurrency, The number of upstream DNS servers that are allowed to initiate requests at the same time" -msgstr "DNS 查询请求并发数,允许同时发起请求的上游 DNS 服务器数量" - -msgid "Idle Timeout" -msgstr "空闲超时" - -msgid "DoH/TCP/DoT Connection Multiplexing idle timeout (default 30 seconds)" -msgstr "DoH/TCP/DoT 连接复用空闲保持时间(默认 30 秒)" - -msgid "TCP/DoT Connection Multiplexing" -msgstr "TCP/DoT 连接复用" - -msgid "Enable TCP/DoT RFC 7766 new Query Pipelining connection multiplexing mode" -msgstr "启用 TCP/DoT RFC 7766 新型 Query Pipelining 连接复用模式" - -msgid "Disable TLS Certificate" -msgstr "禁用 TLS 证书" - -msgid "Disable TLS Servers certificate validation, Can be useful if system CA certificate expires or the system time is out of order" -msgstr "禁用 TLS 服务器证书验证,当系统 CA 证书过期或系统时间错乱时,本选项可能会有用" - -msgid "Enable EDNS client subnet" -msgstr "启用 EDNS 客户端子网" - -msgid "IP Address" -msgstr "IP 地址" - -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 "请提供您在访问国外网站时使用的 IP 地址,这个 IP 子网(0/24)将用作 远程 / 流媒体 DNS 请求的 ECS 地址" - -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 "此功能通常在使用自建 DNS 服务器作为 远程 / 流媒体 DNS 上游时使用(需要上游服务器的支持)" - -msgid "Prevent DNS Leaks" -msgstr "防止 DNS 泄漏" - -msgid "Enable this option fallback policy forces forwarding to remote DNS" -msgstr "启用此选项 fallback 策略会强制转发到远程 DNS" - -msgid "Enable DNS Cache" -msgstr "启用 DNS 缓存" - -msgid "DNS Cache Size" -msgstr "DNS 缓存大小" - -msgid "DNS cache size (in piece)." -msgstr "DNS 缓存大小(单位:条)" - -msgid "Lazy Cache TTL" -msgstr "乐观缓存 TTL" - -msgid "Lazy cache survival time (in second). To disable Lazy Cache, please set to 0." -msgstr "乐观缓存生存时间(单位:秒),要禁用乐观缓存,请设置为 0" - -msgid "Cache Dump" -msgstr "自动保存缓存" - -msgid "Save the cache locally and reload the cache dump on the next startup" -msgstr "保存缓存到本地文件,以供下次启动时重新载入使用" - -msgid "Auto Save Cache Interval" -msgstr "自动保存缓存间隔(秒)" - -msgid "Minimum TTL" -msgstr "覆盖最小 TTL 值(默认 0)" - -msgid "Modify the Minimum TTL value (seconds) for DNS answer results, 0 indicating no modification" -msgstr "修改 DNS 应答结果的最小 TTL 值 (秒),0 表示不修改" - -msgid "Maximum TTL" -msgstr "覆盖最大 TTL 值(默认 0)" - -msgid "Modify the Maximum TTL value (seconds) for DNS answer results, 0 indicating no modification" -msgstr "修改 DNS 应答结果的最大 TTL 值(秒),0 表示不修改" - -msgid "Logs" -msgstr "日志" - -msgid "Clear logs" -msgstr "清空日志" - -msgid "Log Data" -msgstr "日志数据" - -msgid "No log data." -msgstr "无日志数据。" - -msgid "Refresh every %s seconds." -msgstr "每 %s 秒刷新。" - -msgid "Rules" -msgstr "规则列表" - -msgid "Rule Settings" -msgstr "自定义规则列表" - -msgid "Failed to restart mosdns: %s" -msgstr "无法重启 MosDNS:%s" - -msgid "Unable to save contents: %s" -msgstr "无法保存内容:%s" - -msgid "The list of rules only apply to 'Default Config' profiles." -msgstr "规则列表仅适用于 “内置预设” 配置文件。" - -msgid "White Lists" -msgstr "白名单" - -msgid "Added domain names always permit resolution using 'local DNS' with the highest priority (one domain per line, supports domain matching rules)." -msgstr "加入的域名始终允许使用 “本地 DNS” 进行解析,且优先级最高(每个域名一行,支持域名匹配规则)" - -msgid "Block Lists" -msgstr "黑名单" - -msgid "Added domain names will block DNS resolution (one domain per line, supports domain matching rules)." -msgstr "加入的域名将屏蔽 DNS 解析(每个域名一行,支持域名匹配规则)" - -msgid "Grey Lists" -msgstr "灰名单" - -msgid "Added domain names will always use 'Remote DNS' for resolution (one domain per line, supports domain matching rules)." -msgstr "加入的域名始终使用 “远程 DNS” 进行解析(每个域名一行,支持域名匹配规则)" - -msgid "DDNS Lists" -msgstr "DDNS 域名" - -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 "加入的域名始终使用 “本地 DNS” 进行解析,并且强制 TTL 5 秒,解析结果不会进入缓存(每个域名一行,支持域名匹配规则)" - -msgid "Custom Hosts rewrite, for example: baidu.com 10.0.0.1 (one rule per line, supports domain matching rules)." -msgstr "自定义 Hosts 重写,如:baidu.com 10.0.0.1(每个规则一行,支持域名匹配规则)" - -msgid "Redirect" -msgstr "重定向" - -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 "重定向请求的域名。请求域名 A,但返回域名 B 的记录,如:baidu.com qq.com(每个规则一行)" - -msgid "Block PTR" -msgstr "PTR 黑名单" - -msgid "Added domain names will block PTR requests (one domain per line, supports domain matching rules)." -msgstr "加入的域名将阻止 PTR 请求(每个域名一行,支持域名匹配规则)" +#: htdocs/luci-static/resources/view/mosdns/basic.js:142 +msgid "API Options" +msgstr "API 选项" +#: htdocs/luci-static/resources/view/mosdns/basic.js:143 msgid "GeoData Export" msgstr "GeoData 导出" -msgid "GeoSite Tags" -msgstr "GeoSite 标签" +#: htdocs/luci-static/resources/view/mosdns/basic.js:146 +#: htdocs/luci-static/resources/view/mosdns/basic.js:370 +msgid "Enabled" +msgstr "启用" -msgid "Enter the GeoSite.dat category to be exported, Allow add multiple tags" -msgstr "填写需要导出的 GeoSite.dat 类别条目,允许添加多个标签" +#: htdocs/luci-static/resources/view/mosdns/basic.js:150 +msgid "Config File" +msgstr "配置文件" -msgid "GeoIP Tags" -msgstr "GeoIP 标签" +#: htdocs/luci-static/resources/view/mosdns/basic.js:151 +msgid "Default Config" +msgstr "内置预设" -msgid "Enter the GeoIP.dat category to be exported, Allow add multiple tags" -msgstr "输入需要导出的 GeoIP.dat 类别条目,允许添加多个标签" +#: htdocs/luci-static/resources/view/mosdns/basic.js:152 +msgid "Custom Config" +msgstr "自定义" -msgid "Export directory: /var/mosdns" -msgstr "导出目录:/var/mosdns" +#: 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 "DNS 转发" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:177 +msgid "Forward Dnsmasq Domain Name resolution requests to MosDNS" +msgstr "将 Dnsmasq 域名解析请求转发到 MosDNS 服务器" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:181 +msgid "DNS redirect" +msgstr "DNS 重定向" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:181 +msgid "Force redirect all local DNS queries to MosDNS, a.k.a. DNS Hijacking" +msgstr "强制将所有本地 DNS 查询重定向到 MosDNS,即 DNS 劫持。" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:186 +msgid "China DNS prefer IPv4" +msgstr "国内 DNS 首选 IPv4" + +#: 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 "国内 DNS 解析双栈地址时首选 IPv4,目标仅 IPv6 时不受影响" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:191 +msgid "Remote DNS prefer IPv4" +msgstr "远程 DNS 首选 IPv4" + +#: 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 "远程 / 流媒体 DNS 解析双栈地址时首选 IPv4,目标仅 IPv6 时不受影响" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:196 +msgid "Custom China DNS" +msgstr "自定义国内 DNS" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:196 +msgid "Follow WAN interface DNS if not enabled" +msgstr "不启用则使用 WAN 接口 DNS" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:200 +msgid "Apple domains optimization" +msgstr "Apple 域名解析优化" + +#: 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 "配备中国大陆 CDN 的 Apple 域名,始终应答中国大陆 CDN 地址" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:205 +msgid "China DNS server" +msgstr "国内 DNS 服务器" + +#: 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 "腾讯公共 DNS(119.29.29.29)" + +#: 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 "腾讯公共 DNS(119.28.28.28)" + +#: 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 "阿里云公共 DNS(223.5.5.5)" + +#: 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 "阿里云公共 DNS(223.6.6.6)" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:210 +msgid "TrafficRoute Public DNS (180.184.1.1)" +msgstr "火山引擎公共 DNS(180.184.1.1)" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:211 +msgid "TrafficRoute Public DNS (180.184.2.2)" +msgstr "火山引擎公共 DNS(180.184.2.2)" + +#: 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 "信风公共 DNS(114.114.114.114)" + +#: 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 "信风公共 DNS(114.114.115.115)" + +#: 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 "百度公共 DNS(180.76.76.76)" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:215 +msgid "Tencent Public DNS (DNS over HTTPS)" +msgstr "腾讯公共 DNS(DNS over HTTPS)" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:216 +msgid "Aliyun Public DNS (DNS over QUIC)" +msgstr "阿里云公共 DNS(DNS over QUIC)" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:217 +msgid "Aliyun Public DNS (DNS over HTTPS)" +msgstr "阿里云公共 DNS(DNS over HTTPS)" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:218 +msgid "Aliyun Public DNS (DNS over HTTP/3)" +msgstr "阿里云公共 DNS(DNS over HTTP/3)" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:219 +msgid "360 Public DNS (DNS over HTTPS)" +msgstr "360 安全 DNS(DNS over HTTPS)" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:223 +msgid "Remote DNS server" +msgstr "远程 DNS 服务器" + +#: 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 "CloudFlare 公共 DNS(1.1.1.1)" + +#: 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 "CloudFlare 公共 DNS(1.0.0.1)" + +#: 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 "谷歌公共 DNS(8.8.8.8)" + +#: 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 "谷歌公共 DNS(8.8.4.4)" + +#: 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 "Quad9 公共 DNS(9.9.9.9)" + +#: 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 "Quad9 公共 DNS(149.112.112.112)" + +#: 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 "思科公共 DNS(208.67.222.222)" + +#: 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 "思科公共 DNS(208.67.220.220)" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:235 msgid "Custom Stream Media DNS" msgstr "自定义流媒体 DNS" -msgid "Streaming Media DNS server" -msgstr "流媒体 DNS 服务器" - +#: htdocs/luci-static/resources/view/mosdns/basic.js:236 msgid "Netflix, Disney+, Hulu and streaming media rules list will use this DNS" msgstr "自定义 Netflix、Disney+、Hulu 以及 “流媒体” 规则列表的 DNS 服务器" +#: htdocs/luci-static/resources/view/mosdns/basic.js:240 +msgid "Streaming Media DNS server" +msgstr "流媒体 DNS 服务器" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:252 +msgid "Bootstrap DNS servers" +msgstr "Bootstrap DNS 服务器" + +#: 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 "Bootstrap DNS 服务器用于解析您指定为上游的 DoH / DoT 解析器的 IP 地址" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:267 +msgid "Concurrent" +msgstr "DNS 服务器并发数(默认 2)" + +#: 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 "DNS 查询请求并发数,允许同时发起请求的上游 DNS 服务器数量" + +#: 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 "DoH/TCP/DoT 连接复用空闲保持时间(默认 30 秒)" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:279 +msgid "TCP/DoT Connection Multiplexing" +msgstr "TCP/DoT 连接复用" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:280 +msgid "" +"Enable TCP/DoT RFC 7766 new Query Pipelining connection multiplexing mode" +msgstr "启用 TCP/DoT RFC 7766 新型 Query Pipelining 连接复用模式" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:285 +msgid "Disable TLS Certificate" +msgstr "禁用 TLS 证书" + +#: 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 "" +"禁用 TLS 服务器证书验证,当系统 CA 证书过期或系统时间错乱时,本选项可能会有用" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:292 +msgid "Enable EDNS client subnet" +msgstr "启用 EDNS 客户端子网" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:297 +msgid "IP Address" +msgstr "IP 地址" + +#: 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 "" +"请提供您在访问国外网站时使用的 IP 地址,这个 IP 子网(0/24)将用作 远程 / 流" +"媒体 DNS 请求的 ECS 地址" + +#: 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 "" +"此功能通常在使用自建 DNS 服务器作为 远程 / 流媒体 DNS 上游时使用(需要上游服" +"务器的支持)" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:303 +msgid "Prevent DNS Leaks" +msgstr "防止 DNS 泄漏" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:304 +msgid "Enable this option fallback policy forces forwarding to remote DNS" +msgstr "启用此选项 fallback 策略会强制转发到远程 DNS" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:309 +msgid "Enable DNS Cache" +msgstr "启用 DNS 缓存" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:314 +msgid "DNS Cache Size" +msgstr "DNS 缓存大小" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:319 +msgid "Lazy Cache TTL" +msgstr "乐观缓存 TTL" + +#: 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 "乐观缓存生存时间(单位:秒),要禁用乐观缓存,请设置为 0" + +#: 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 "覆盖最小 TTL 值(默认 0)" + +#: 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 "修改 DNS 应答结果的最小 TTL 值 (秒),0 表示不修改" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:343 +msgid "Maximum TTL" +msgstr "覆盖最大 TTL 值(默认 0)" + +#: 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 "修改 DNS 应答结果的最大 TTL 值(秒),0 表示不修改" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:349 +msgid "Disable RR Type 65 (HTTPS/SVCB)" +msgstr "禁用 RR Type 65 (HTTPS/SVCB)" + +#: 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 "" +"屏蔽 DNS 类型 65 记录(HTTPS/SVCB,用于 HTTP/3、ECH 等),强制仅使用 A/AAAA " +"解析。" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:354 +msgid "Enable DNS ADblock" +msgstr "启用 DNS 广告过滤" + +#: 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 "使用自定义规则来源时,请使用 MosDNS 支持的规则类型(域名列表)" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:361 +msgid "Support for local files, such as: file:///var/mosdns/example.txt" +msgstr "支持本地文件,例如:file:///var/mosdns/example.txt" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:371 +#, fuzzy +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 "" +"将解析结果与 Cloudflare IP 范围进行匹配,当匹配成功时,使用 “自选 IP” 作为解" +"析结果(实验性功能)" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:377 +msgid "Custom IP" +msgstr "自选 IP" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:382 +msgid "Cloudflare IP Ranges" +msgstr "Cloudflare IP 范围" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:383 +msgid "" +"IPv4 CIDR: https://www.cloudflare.com/ips-v4
IPv6 CIDR: https://www.cloudflare.com/ips-" +"v6" +msgstr "" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:402 +msgid "API Listen port" +msgstr "API 监听端口" + +#: 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 "刷新 DNS 缓存会清空 MosDNS 所有 IP 地址和 DNS 解析缓存。" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:410 +msgid "Flush DNS Cache" +msgstr "刷新 DNS 缓存" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:433 +msgid "Configuration Editor" +msgstr "配置编辑器" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:434 +#, fuzzy +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 "" +"这是文件 “/etc/mosdns/config_custom.yaml” 的内容,您的 MosDNS 配置将从此文件" +"生成。仅接受 yaml 格式的配置内容。" + +#: 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 "无法保存内容:%s" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:460 +msgid "GeoSite Tags" +msgstr "GeoSite 标签" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:461 +msgid "Enter the GeoSite.dat category to be exported, Allow add multiple tags" +msgstr "填写需要导出的 GeoSite.dat 类别条目,允许添加多个标签" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:462 +#: htdocs/luci-static/resources/view/mosdns/basic.js:467 +msgid "Export directory: /var/mosdns" +msgstr "导出目录:/var/mosdns" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:465 +msgid "GeoIP Tags" +msgstr "GeoIP 标签" + +#: htdocs/luci-static/resources/view/mosdns/basic.js:466 +msgid "Enter the GeoIP.dat category to be exported, Allow add multiple tags" +msgstr "输入需要导出的 GeoIP.dat 类别条目,允许添加多个标签" + +#: htdocs/luci-static/resources/view/mosdns/logs.js:27 +msgid "No log data." +msgstr "无日志数据。" + +#: htdocs/luci-static/resources/view/mosdns/logs.js:43 +#, fuzzy +msgid "Failed to clean logs." +msgstr "无法重启 MosDNS:%s" + +#: 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 "每 %s 秒刷新。" + +#: 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 "DDNS 域名" + +#: 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 "PTR 黑名单" + +#: htdocs/luci-static/resources/view/mosdns/rules.js:31 msgid "Streaming Media" msgstr "流媒体" -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 "启用 “自定义流媒体 DNS” 时,加入的域名始终使用 “流媒体 DNS 服务器” 进行解析(每个域名一行,支持域名匹配规则)" +#: 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 "" +"加入的域名始终允许使用 “本地 DNS” 进行解析,且优先级最高(每个域名一行,支持" +"域名匹配规则)" + +#: 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 "加入的域名将屏蔽 DNS 解析(每个域名一行,支持域名匹配规则)" + +#: 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 "" +"加入的域名始终使用 “远程 DNS” 进行解析(每个域名一行,支持域名匹配规则)" + +#: 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 "" +"加入的域名始终使用 “本地 DNS” 进行解析,并且强制 TTL 5 秒,解析结果不会进入缓" +"存(每个域名一行,支持域名匹配规则)" + +#: 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 "" +"自定义 Hosts 重写,如:baidu.com 10.0.0.1(每个规则一行,支持域名匹配规则)" + +#: 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 "" +"重定向请求的域名。请求域名 A,但返回域名 B 的记录,如:baidu.com qq.com(每个" +"规则一行)" + +#: 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 "加入的域名将阻止 PTR 请求(每个域名一行,支持域名匹配规则)" + +#: 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 "" +"启用 “自定义流媒体 DNS” 时,加入的域名始终使用 “流媒体 DNS 服务器” 进行解析" +"(每个域名一行,支持域名匹配规则)" + +#: 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 "无法重启 MosDNS:%s" + +#: 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 +#, fuzzy, javascript-format +msgid "Update failed: %s" +msgstr "更新失败: %s" + +#: htdocs/luci-static/resources/view/mosdns/update.js:30 +msgid "Update GeoIP & GeoSite databases" +msgstr "更新广告规则、GeoIP & GeoSite 数据库" + +#: 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 "通过定时任务自动更新 GeoIP 和 GeoSite 数据库以及广告过滤规则。" + +#: 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 "GeoIP 类型" + +#: htdocs/luci-static/resources/view/mosdns/update.js:57 +msgid "Little: only include Mainland China and Private IP addresses." +msgstr "轻量:仅包含中国大陆和私有 IP 地址。" + +#: htdocs/luci-static/resources/view/mosdns/update.js:59 +msgid "Full: includes all Countries and Private IP addresses." +msgstr "全量:包含所有国家和私有 IP 地址。" + +#: 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 "GitHub 代理" + +#: htdocs/luci-static/resources/view/mosdns/update.js:67 +msgid "" +"Update data files with GitHub Proxy, leave blank to disable proxy downloads." +msgstr "通过 GitHub 代理更新数据文件,留空则禁用代理下载。" + +#: 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 "检查并更新 GeoData 数据库。" + +#: 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 "日志" diff --git a/luci-app-mosdns/root/etc/init.d/mosdns b/luci-app-mosdns/root/etc/init.d/mosdns index 4c9fcd89..66423ae9 100755 --- a/luci-app-mosdns/root/etc/init.d/mosdns +++ b/luci-app-mosdns/root/etc/init.d/mosdns @@ -1,6 +1,6 @@ #!/bin/sh /etc/rc.common # Copyright (C) 2020-2022, IrineSistiana -# Copyright (C) 2023-2024, sbwml +# Copyright (C) 2023-2026, sbwml 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() { diff --git a/luci-app-mosdns/root/usr/share/mosdns/mosdns.sh b/luci-app-mosdns/root/usr/share/mosdns/mosdns.sh deleted file mode 100755 index b0534dae..00000000 --- a/luci-app-mosdns/root/usr/share/mosdns/mosdns.sh +++ /dev/null @@ -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 diff --git a/luci-app-mosdns/root/usr/share/mosdns/mosdns.uc b/luci-app-mosdns/root/usr/share/mosdns/mosdns.uc new file mode 100755 index 00000000..c75254e3 --- /dev/null +++ b/luci-app-mosdns/root/usr/share/mosdns/mosdns.uc @@ -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); +} diff --git a/luci-app-mosdns/root/usr/share/rpcd/acl.d/luci-app-mosdns.json b/luci-app-mosdns/root/usr/share/rpcd/acl.d/luci-app-mosdns.json index 3dc05af2..35a86d07 100644 --- a/luci-app-mosdns/root/usr/share/rpcd/acl.d/luci-app-mosdns.json +++ b/luci-app-mosdns/root/usr/share/rpcd/acl.d/luci-app-mosdns.json @@ -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 @@ } } } - diff --git a/luci-app-mosdns/root/usr/share/rpcd/ucode/mosdns.uc b/luci-app-mosdns/root/usr/share/rpcd/ucode/mosdns.uc new file mode 100644 index 00000000..4b09f392 --- /dev/null +++ b/luci-app-mosdns/root/usr/share/rpcd/ucode/mosdns.uc @@ -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 }; diff --git a/luci-app-mtphotos/Makefile b/luci-app-mtphotos/Makefile index a6bd4708..c8bf3931 100644 --- a/luci-app-mtphotos/Makefile +++ b/luci-app-mtphotos/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.0.2-20240822 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for MTPhotos LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +luci-lib-docker +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd +luci-lib-docker define Package/luci-app-mtphotos/conffiles /etc/config/mtphotos diff --git a/luci-app-nastools/Makefile b/luci-app-nastools/Makefile index bceaf5f9..3ff022e3 100644 --- a/luci-app-nastools/Makefile +++ b/luci-app-nastools/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.1.3-20240822 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for nastools LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd define Package/luci-app-nastools/conffiles /etc/config/nastools diff --git a/luci-app-navidrome/Makefile b/luci-app-navidrome/Makefile index da8f91b6..519515f0 100644 --- a/luci-app-navidrome/Makefile +++ b/luci-app-navidrome/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.0.1-20240822 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for Navidrome LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd define Package/luci-app-navidrome/conffiles /etc/config/navidrome diff --git a/luci-app-nextcloud/Makefile b/luci-app-nextcloud/Makefile index 42fc44e1..339f677d 100644 --- a/luci-app-nextcloud/Makefile +++ b/luci-app-nextcloud/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.1.1-20240822 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for nextcloud LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd define Package/luci-app-nextcloud/conffiles /etc/config/nextcloud diff --git a/luci-app-oneapi/Makefile b/luci-app-oneapi/Makefile index 0cbf6daf..77d07f0a 100644 --- a/luci-app-oneapi/Makefile +++ b/luci-app-oneapi/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.0.1-20250403 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for OneAPI LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +zoneinfo-asia +docker +dockerd +luci-lib-taskd +luci-lib-docker +LUCI_DEPENDS:=+lsblk +zoneinfo-asia +docker +luci-lib-taskd +luci-lib-docker define Package/luci-app-oneapi/conffiles /etc/config/oneapi diff --git a/luci-app-openwebui/Makefile b/luci-app-openwebui/Makefile index 11e3563a..54970c40 100644 --- a/luci-app-openwebui/Makefile +++ b/luci-app-openwebui/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.0.8-20250207 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for OpenWebUI LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +zoneinfo-asia +docker +dockerd +luci-lib-taskd +luci-lib-docker +LUCI_DEPENDS:=+lsblk +zoneinfo-asia +docker +luci-lib-taskd +luci-lib-docker define Package/luci-app-openwebui/conffiles /etc/config/openwebui diff --git a/luci-app-owntone/Makefile b/luci-app-owntone/Makefile index 7de66e28..715cac02 100644 --- a/luci-app-owntone/Makefile +++ b/luci-app-owntone/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.0.2-20240822 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for Owntone LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd define Package/luci-app-owntone/conffiles /etc/config/owntone diff --git a/luci-app-penpot/Makefile b/luci-app-penpot/Makefile index 2a136726..d0a09c3b 100644 --- a/luci-app-penpot/Makefile +++ b/luci-app-penpot/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.0.0-20240822 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for Penpot LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +docker-compose +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd +docker-compose define Package/luci-app-penpot/conffiles /etc/config/penpot diff --git a/luci-app-photoprism/Makefile b/luci-app-photoprism/Makefile index 70cdc320..ca25b7c1 100644 --- a/luci-app-photoprism/Makefile +++ b/luci-app-photoprism/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.0.3-20240822 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for PhotoPrism LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd define Package/luci-app-photoprism/conffiles /etc/config/photoprism diff --git a/luci-app-plex/Makefile b/luci-app-plex/Makefile index d37ff8bc..32847c3c 100644 --- a/luci-app-plex/Makefile +++ b/luci-app-plex/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.0.2-20240822 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for Plex LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +luci-lib-docker +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd +luci-lib-docker define Package/luci-app-plex/conffiles /etc/config/plex diff --git a/luci-app-pve/Makefile b/luci-app-pve/Makefile index 6a473c4e..a4c4e98b 100644 --- a/luci-app-pve/Makefile +++ b/luci-app-pve/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=8.3.2-20250106 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for pve LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +vmease +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd +vmease define Package/luci-app-pve/conffiles /etc/config/pve diff --git a/luci-app-runmynas/Makefile b/luci-app-runmynas/Makefile index 0cc80c4d..610c41c1 100644 --- a/luci-app-runmynas/Makefile +++ b/luci-app-runmynas/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.1.1-20231208 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for runmynas LUCI_PKGARCH:=all -LUCI_DEPENDS:=+docker +dockerd +luci-lib-iform +luci-lib-taskd +LUCI_DEPENDS:=+docker +luci-lib-iform +luci-lib-taskd LUCI_EXTRA_DEPENDS:=luci-lib-iform (>=1.1) define Package/luci-app-runmynas/conffiles diff --git a/luci-app-shadowrt/Makefile b/luci-app-shadowrt/Makefile index 0f613bf1..43ac1046 100644 --- a/luci-app-shadowrt/Makefile +++ b/luci-app-shadowrt/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.1.7-r1 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for shadowrt LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +docker-lan-bridge +luci-lib-taskd +LUCI_DEPENDS:=+lsblk +docker +docker-lan-bridge +luci-lib-taskd define Package/luci-app-shadowrt/conffiles /etc/config/shadowrt diff --git a/luci-app-typecho/Makefile b/luci-app-typecho/Makefile index 339eda46..15bc0ff2 100644 --- a/luci-app-typecho/Makefile +++ b/luci-app-typecho/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.0.2-20240822 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for TypeCho LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +luci-lib-docker +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd +luci-lib-docker define Package/luci-app-typecho/conffiles /etc/config/typecho diff --git a/luci-app-ubuntu/Makefile b/luci-app-ubuntu/Makefile index 483a7500..edb68855 100644 --- a/luci-app-ubuntu/Makefile +++ b/luci-app-ubuntu/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.1.1-20240822 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for ubuntu LUCI_PKGARCH:=all -LUCI_DEPENDS:=+docker +dockerd +luci-lib-iform +luci-lib-taskd +LUCI_DEPENDS:=+docker +luci-lib-iform +luci-lib-taskd LUCI_EXTRA_DEPENDS:=luci-lib-iform (>=1.1) define Package/luci-app-ubuntu/conffiles diff --git a/luci-app-ubuntu2/Makefile b/luci-app-ubuntu2/Makefile index 4ea05eae..0b4124fc 100644 --- a/luci-app-ubuntu2/Makefile +++ b/luci-app-ubuntu2/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.1.0-20251012 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for Ubuntu2 LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd define Package/luci-app-ubuntu2/conffiles /etc/config/ubuntu2 diff --git a/luci-app-unifi/Makefile b/luci-app-unifi/Makefile index c30366e8..2c1014c5 100644 --- a/luci-app-unifi/Makefile +++ b/luci-app-unifi/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.0.2-20240822 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for UnifiController LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd define Package/luci-app-unifi/conffiles /etc/config/unifi diff --git a/luci-app-uptimekuma/Makefile b/luci-app-uptimekuma/Makefile index 142f281c..2f113a3e 100644 --- a/luci-app-uptimekuma/Makefile +++ b/luci-app-uptimekuma/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.0.1-20251011 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for UptimeKuma LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +zoneinfo-asia +docker +dockerd +luci-lib-taskd +luci-lib-docker +LUCI_DEPENDS:=+lsblk +zoneinfo-asia +docker +luci-lib-taskd +luci-lib-docker define Package/luci-app-uptimekuma/conffiles /etc/config/uptimekuma diff --git a/luci-app-vaultwarden/Makefile b/luci-app-vaultwarden/Makefile index d14f22d9..87c8007f 100644 --- a/luci-app-vaultwarden/Makefile +++ b/luci-app-vaultwarden/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.0.1-20240822 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for Vaultwarden LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd define Package/luci-app-vaultwarden/conffiles /etc/config/vaultwarden diff --git a/luci-app-webvirtcloud/Makefile b/luci-app-webvirtcloud/Makefile index dd98959a..b1addfe8 100644 --- a/luci-app-webvirtcloud/Makefile +++ b/luci-app-webvirtcloud/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=0.8.5-20241221-1 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for webvirtcloud LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +vmease +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd +vmease define Package/luci-app-webvirtcloud/conffiles /etc/config/webvirtcloud diff --git a/luci-app-wxedge/Makefile b/luci-app-wxedge/Makefile index ec08ae31..d02c747c 100644 --- a/luci-app-wxedge/Makefile +++ b/luci-app-wxedge/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.1.7-20250516 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for wxedge LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd define Package/luci-app-wxedge/conffiles /etc/config/wxedge diff --git a/luci-app-xteve/Makefile b/luci-app-xteve/Makefile index 8c44cb2f..cd59e329 100644 --- a/luci-app-xteve/Makefile +++ b/luci-app-xteve/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.0.2-20240822 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for Xteve LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +luci-lib-docker +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd +luci-lib-docker define Package/luci-app-xteve/conffiles /etc/config/xteve diff --git a/luci-app-xunlei/Makefile b/luci-app-xunlei/Makefile index 213c711d..ee38efe8 100644 --- a/luci-app-xunlei/Makefile +++ b/luci-app-xunlei/Makefile @@ -3,11 +3,11 @@ include $(TOPDIR)/rules.mk PKG_VERSION:=1.0.3-20240822 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI support for Xunlei LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd define Package/luci-app-xunlei/conffiles /etc/config/xunlei diff --git a/luci-app-zdinnav/Makefile b/luci-app-zdinnav/Makefile index d092a382..bf51b15c 100755 --- a/luci-app-zdinnav/Makefile +++ b/luci-app-zdinnav/Makefile @@ -5,12 +5,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-zdinnav LUCI_TITLE:=LuCI support for ZdinNav LUCI_PKGARCH:=all -LUCI_DEPENDS:=+lsblk +docker +dockerd +luci-lib-taskd +luci-lib-docker +docker-compose +luci-compat +LUCI_DEPENDS:=+lsblk +docker +luci-lib-taskd +luci-lib-docker +docker-compose +luci-compat PKG_MAINTAINER:=tkme PKG_VERSION:=1.1.1 -PKG_RELEASE:=1 +PKG_RELEASE:=2 define Package/luci-app-zdinnav/conffiles /etc/config/zdinnav diff --git a/mosdns/Makefile b/mosdns/Makefile index c5966bc8..6d93e149 100644 --- a/mosdns/Makefile +++ b/mosdns/Makefile @@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=mosdns PKG_VERSION:=5.3.4 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/IrineSistiana/mosdns/tar.gz/v$(PKG_VERSION)? diff --git a/mosdns/patches/100-mosdns-update-dependencies.patch b/mosdns/patches/100-mosdns-update-dependencies.patch new file mode 100644 index 00000000..15fbbdee --- /dev/null +++ b/mosdns/patches/100-mosdns-update-dependencies.patch @@ -0,0 +1,238 @@ +From 201408484de552cb927f6a50b76a34d65c8ac8c6 Mon Sep 17 00:00:00 2001 +From: sbwml +Date: Fri, 20 Mar 2026 10:39:22 +0800 +Subject: [PATCH] mosdns: update dependencies + +Signed-off-by: sbwml +--- + .github/workflows/release.yml | 2 +- + .github/workflows/test.yml | 2 +- + go.mod | 36 +++++++++---------- + go.sum | 68 +++++++++++++++++------------------ + pkg/query_context/context.go | 1 - + 5 files changed, 54 insertions(+), 55 deletions(-) + +--- a/.github/workflows/release.yml ++++ b/.github/workflows/release.yml +@@ -14,7 +14,7 @@ jobs: + - name: Set up Go + uses: actions/setup-go@v6 + with: +- go-version: "1.25" ++ go-version: "1.26" + check-latest: true + cache: true + +--- a/.github/workflows/test.yml ++++ b/.github/workflows/test.yml +@@ -12,7 +12,7 @@ jobs: + - name: Set up Go + uses: actions/setup-go@v6 + with: +- go-version: "1.25" ++ go-version: "1.26" + check-latest: true + cache: true + +--- a/go.mod ++++ b/go.mod +@@ -1,30 +1,30 @@ + module github.com/IrineSistiana/mosdns/v5 + +-go 1.24.9 ++go 1.25.0 + + require ( + github.com/IrineSistiana/go-bytes-pool v0.0.0-20230918115058-c72bd9761c57 +- github.com/go-chi/chi/v5 v5.2.3 +- github.com/go-viper/mapstructure/v2 v2.4.0 ++ github.com/go-chi/chi/v5 v5.2.5 ++ github.com/go-viper/mapstructure/v2 v2.5.0 + github.com/google/nftables v0.3.0 + github.com/kardianos/service v1.2.4 +- github.com/klauspost/compress v1.18.2 +- github.com/miekg/dns v1.1.70 ++ github.com/klauspost/compress v1.18.4 ++ github.com/miekg/dns v1.1.72 + github.com/mitchellh/mapstructure v1.5.0 + github.com/nadoo/ipset v0.5.0 + github.com/prometheus/client_golang v1.23.2 +- github.com/quic-go/quic-go v0.58.1 ++ github.com/quic-go/quic-go v0.59.0 + github.com/spf13/cobra v1.10.2 + github.com/spf13/viper v1.21.0 + github.com/stretchr/testify v1.11.1 + github.com/vishvananda/netlink v1.3.0 + go.uber.org/zap v1.27.1 + go4.org/netipx v0.0.0-20231129151722-fdeea329fbba +- golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 +- golang.org/x/net v0.48.0 +- golang.org/x/sync v0.19.0 +- golang.org/x/sys v0.40.0 +- golang.org/x/time v0.14.0 ++ golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90 ++ golang.org/x/net v0.52.0 ++ golang.org/x/sync v0.20.0 ++ golang.org/x/sys v0.42.0 ++ golang.org/x/time v0.15.0 + google.golang.org/protobuf v1.36.11 + ) + +@@ -37,14 +37,14 @@ require ( + github.com/fsnotify/fsnotify v1.9.0 // indirect + github.com/google/go-cmp v0.7.0 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect +- github.com/mdlayher/netlink v1.8.0 // indirect ++ github.com/mdlayher/netlink v1.9.0 // indirect + github.com/mdlayher/socket v0.5.1 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/pelletier/go-toml/v2 v2.2.4 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/prometheus/client_model v0.6.2 // indirect + github.com/prometheus/common v0.67.5 // indirect +- github.com/prometheus/procfs v0.19.2 // indirect ++ github.com/prometheus/procfs v0.20.1 // indirect + github.com/quic-go/qpack v0.6.0 // indirect + github.com/rogpeppe/go-internal v1.13.1 // indirect + github.com/sagikazarmark/locafero v0.12.0 // indirect +@@ -55,11 +55,11 @@ require ( + github.com/vishvananda/netns v0.0.4 // indirect + go.uber.org/mock v0.6.0 // indirect + go.uber.org/multierr v1.11.0 // indirect +- go.yaml.in/yaml/v2 v2.4.3 // indirect ++ go.yaml.in/yaml/v2 v2.4.4 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect +- golang.org/x/crypto v0.46.0 // indirect +- golang.org/x/mod v0.32.0 // indirect +- golang.org/x/text v0.33.0 // indirect +- golang.org/x/tools v0.40.0 // indirect ++ golang.org/x/crypto v0.49.0 // indirect ++ golang.org/x/mod v0.34.0 // indirect ++ golang.org/x/text v0.35.0 // indirect ++ golang.org/x/tools v0.43.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + ) +--- a/go.sum ++++ b/go.sum +@@ -13,10 +13,10 @@ github.com/frankban/quicktest v1.14.6 h1 + github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= + github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= + github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +-github.com/go-chi/chi/v5 v5.2.3 h1:WQIt9uxdsAbgIYgid+BpYc+liqQZGMHRaUwp0JUcvdE= +-github.com/go-chi/chi/v5 v5.2.3/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops= +-github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= +-github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= ++github.com/go-chi/chi/v5 v5.2.5 h1:Eg4myHZBjyvJmAFjFvWgrqDTXFyOzjj7YIm3L3mu6Ug= ++github.com/go-chi/chi/v5 v5.2.5/go.mod h1:X7Gx4mteadT3eDOMTsXzmI4/rwUpOwBHLpAfupzFJP0= ++github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= ++github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= + github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= + github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= + github.com/google/nftables v0.3.0 h1:bkyZ0cbpVeMHXOrtlFc8ISmfVqq5gPJukoYieyVmITg= +@@ -25,20 +25,20 @@ github.com/inconshreveable/mousetrap v1. + github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= + github.com/kardianos/service v1.2.4 h1:XNlGtZOYNx2u91urOdg/Kfmc+gfmuIo1Dd3rEi2OgBk= + github.com/kardianos/service v1.2.4/go.mod h1:E4V9ufUuY82F7Ztlu1eN9VXWIQxg8NoLQlmFe0MtrXc= +-github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk= +-github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= ++github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= ++github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= + github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= + github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= + github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= + github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= + github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= + github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +-github.com/mdlayher/netlink v1.8.0 h1:e7XNIYJKD7hUct3Px04RuIGJbBxy1/c4nX7D5YyvvlM= +-github.com/mdlayher/netlink v1.8.0/go.mod h1:UhgKXUlDQhzb09DrCl2GuRNEglHmhYoWAHid9HK3594= ++github.com/mdlayher/netlink v1.9.0 h1:G8+GLq2x3v4D4MVIqDdNUhTUC7TKiCy/6MDkmItfKco= ++github.com/mdlayher/netlink v1.9.0/go.mod h1:YBnl5BXsCoRuwBjKKlZ+aYmEoq0r12FDA/3JC+94KDg= + github.com/mdlayher/socket v0.5.1 h1:VZaqt6RkGkt2OE9l3GcC6nZkqD3xKeQLyfleW/uBcos= + github.com/mdlayher/socket v0.5.1/go.mod h1:TjPLHI1UgwEv5J1B5q0zTZq12A/6H7nKmtTanQE37IQ= +-github.com/miekg/dns v1.1.70 h1:DZ4u2AV35VJxdD9Fo9fIWm119BsQL5cZU1cQ9s0LkqA= +-github.com/miekg/dns v1.1.70/go.mod h1:+EuEPhdHOsfk6Wk5TT2CzssZdqkmFhf8r+aVyDEToIs= ++github.com/miekg/dns v1.1.72 h1:vhmr+TF2A3tuoGNkLDFK9zi36F2LS+hKTRW0Uf8kbzI= ++github.com/miekg/dns v1.1.72/go.mod h1:+EuEPhdHOsfk6Wk5TT2CzssZdqkmFhf8r+aVyDEToIs= + github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= + github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +@@ -53,12 +53,12 @@ github.com/prometheus/client_model v0.6. + github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= + github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= + github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= +-github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws= +-github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= ++github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc= ++github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo= + github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8= + github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII= +-github.com/quic-go/quic-go v0.58.1 h1:J0s55TVauDbnCEY5tU2B8e7nYb3gnKMSez5Fwi1dl2s= +-github.com/quic-go/quic-go v0.58.1/go.mod h1:upnsH4Ju1YkqpLXC305eW3yDZ4NfnNbmQRCMWS58IKU= ++github.com/quic-go/quic-go v0.59.0 h1:OLJkp1Mlm/aS7dpKgTc6cnpynnD2Xg7C1pwL6vy/SAw= ++github.com/quic-go/quic-go v0.59.0/go.mod h1:upnsH4Ju1YkqpLXC305eW3yDZ4NfnNbmQRCMWS58IKU= + github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= + github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= + github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +@@ -91,32 +91,32 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSx + go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= + go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= + go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +-go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= +-go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= ++go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= ++go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= + go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= + go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= + go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M= + go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y= +-golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= +-golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= +-golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 h1:fQsdNF2N+/YewlRZiricy4P1iimyPKZ/xwniHj8Q2a0= +-golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU= +-golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c= +-golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU= +-golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +-golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +-golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +-golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= ++golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= ++golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= ++golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90 h1:jiDhWWeC7jfWqR9c/uplMOqJ0sbNlNWv0UkzE0vX1MA= ++golang.org/x/exp v0.0.0-20260312153236-7ab1446f8b90/go.mod h1:xE1HEv6b+1SCZ5/uscMRjUBKtIxworgEcEi+/n9NQDQ= ++golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI= ++golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY= ++golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= ++golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= ++golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= ++golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= + golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= + golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +-golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= +-golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +-golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= +-golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= +-golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +-golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= +-golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= +-golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= ++golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= ++golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= ++golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= ++golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= ++golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= ++golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= ++golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s= ++golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0= + google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= + google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= + gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +--- a/pkg/query_context/context.go ++++ b/pkg/query_context/context.go +@@ -108,7 +108,6 @@ func (ctx *Context) QQuestion() dns.Ques + // It's a helper func for searching opt in Q() manually. + func (ctx *Context) QOpt() *dns.OPT { + opt := findOpt(ctx.query) +- ctx.query.IsEdns0() + if opt == nil { + panic("query opt is missing") + } diff --git a/nikki/Makefile b/nikki/Makefile index 4bc28daa..2348da76 100644 --- a/nikki/Makefile +++ b/nikki/Makefile @@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=nikki PKG_VERSION:=2026.03.10 -PKG_RELEASE:=4 +PKG_RELEASE:=5 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) diff --git a/nikki/files/nikki.init b/nikki/files/nikki.init index 5fe2fd4c..fa1144d0 100644 --- a/nikki/files/nikki.init +++ b/nikki/files/nikki.init @@ -28,7 +28,7 @@ boot_func() { } boot() { - boot_func & + boot_func < /dev/null > /dev/null 2>&1 & } start_service() { diff --git a/nikki/files/ucode/include.uc b/nikki/files/ucode/include.uc index f100bed6..97f824f1 100644 --- a/nikki/files/ucode/include.uc +++ b/nikki/files/ucode/include.uc @@ -78,7 +78,7 @@ export function get_cgroups() { export function load_profile() { let result = {}; - const process = popen('yq -M -p yaml -o json /etc/nikki/run/config.yaml 2>/dev/null'); + const process = popen('yq -M -p yaml -o json /etc/nikki/run/config.yaml'); if (process) { result = json(process); process.close(); diff --git a/routergo/Makefile b/routergo/Makefile index 52ffa83c..6fa68301 100644 --- a/routergo/Makefile +++ b/routergo/Makefile @@ -11,7 +11,7 @@ PKG_ARCH_routergo:=$(ARCH) PKG_NAME:=routergo PKG_VERSION:=0.14.10 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE:=$(PKG_NAME)-binary-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://github.com/Carseason/openwrt-packages/releases/download/prebuilt/ PKG_HASH:=skip @@ -27,7 +27,7 @@ define Package/$(PKG_NAME) CATEGORY:=Network SUBMENU:=Web Servers/Proxies TITLE:=RouterGo - DEPENDS:=@(x86_64||aarch64||arm) +docker +dockerd +luci-app-linkease + DEPENDS:=@(x86_64||aarch64||arm) +docker +luci-app-linkease URL:=https://github.com/Carseason/openwrt-packages endef diff --git a/v2dat/Makefile b/v2dat/Makefile index a2765d29..359677a4 100644 --- a/v2dat/Makefile +++ b/v2dat/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=v2dat PKG_SOURCE_DATE:=2022-12-15 PKG_SOURCE_VERSION:=47b8ee51fb528e11e1a83453b7e767a18d20d1f7 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE:=$(PKG_NAME)-$(PKG_SOURCE_DATE).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/urlesistiana/v2dat/tar.gz/$(PKG_SOURCE_VERSION)? diff --git a/v2dat/patches/100-format-logtime.patch b/v2dat/patches/100-format-logtime.patch index a3024e6d..4ccc1ed6 100644 --- a/v2dat/patches/100-format-logtime.patch +++ b/v2dat/patches/100-format-logtime.patch @@ -1,7 +1,7 @@ -From 7c6a252ab3f7d9aeb743f9fa8d0cc8c7402f984d Mon Sep 17 00:00:00 2001 +From 226cb45cc97c52fc0383a5b5172a131f65921f4a Mon Sep 17 00:00:00 2001 From: sbwml Date: Wed, 20 Sep 2023 20:52:27 +0800 -Subject: [PATCH] format logtime +Subject: [PATCH 1/3] format logtime --- mlog/logger.go | 15 +++++++++++++-- diff --git a/v2dat/patches/101-v2dat-update-dependencies.patch b/v2dat/patches/101-v2dat-update-dependencies.patch index f6c940e7..ac8381e5 100644 --- a/v2dat/patches/101-v2dat-update-dependencies.patch +++ b/v2dat/patches/101-v2dat-update-dependencies.patch @@ -1,44 +1,44 @@ -From d5f31a032bae130c83bb50b8679776cf1b33f05d Mon Sep 17 00:00:00 2001 +From 0e465de6bc63d71dd7371209bbaaf9350e2fc567 Mon Sep 17 00:00:00 2001 From: sbwml -Date: Mon, 30 Jun 2025 15:08:51 +0800 -Subject: [PATCH] v2dat: update dependencies +Date: Fri, 20 Mar 2026 09:45:03 +0800 +Subject: [PATCH 2/3] v2dat: update dependencies Signed-off-by: sbwml --- - go.mod | 14 ++++++-------- - go.sum | 41 +++++++++++++---------------------------- - 2 files changed, 19 insertions(+), 36 deletions(-) + go.mod | 15 ++++++--------- + go.sum | 47 +++++++++++++++++------------------------------ + 2 files changed, 23 insertions(+), 39 deletions(-) --- a/go.mod +++ b/go.mod -@@ -1,18 +1,16 @@ +@@ -1,18 +1,15 @@ module github.com/urlesistiana/v2dat -go 1.19 -+go 1.22 ++go 1.23 require ( - github.com/spf13/cobra v1.6.1 - go.uber.org/zap v1.24.0 - google.golang.org/protobuf v1.28.1 -+ github.com/spf13/cobra v1.9.1 -+ go.uber.org/zap v1.27.0 -+ google.golang.org/protobuf v1.36.6 ++ github.com/spf13/cobra v1.10.2 ++ go.uber.org/zap v1.27.1 ++ google.golang.org/protobuf v1.36.11 ) require ( - github.com/google/go-cmp v0.5.9 // indirect +- github.com/google/go-cmp v0.5.9 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/spf13/pflag v1.0.5 // indirect - github.com/stretchr/testify v1.8.1 // indirect - go.uber.org/atomic v1.10.0 // indirect - go.uber.org/multierr v1.9.0 // indirect -+ github.com/spf13/pflag v1.0.6 // indirect ++ github.com/spf13/pflag v1.0.10 // indirect + go.uber.org/multierr v1.11.0 // indirect ) --- a/go.sum +++ b/go.sum -@@ -1,42 +1,27 @@ +@@ -1,42 +1,29 @@ -github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -47,9 +47,11 @@ Signed-off-by: sbwml github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= - github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= - github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +-github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +-github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= ++github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= ++github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= @@ -65,10 +67,11 @@ Signed-off-by: sbwml -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -+github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= -+github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= -+github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= -+github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= ++github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU= ++github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4= ++github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= ++github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= ++github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= @@ -86,10 +89,11 @@ Signed-off-by: sbwml +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -+go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= -+go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -+google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -+google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= ++go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= ++go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= ++go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= ++google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= ++google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/v2dat/patches/102-perf-unpack-Use-memory-mapping-to-reduce-memory-usag.patch b/v2dat/patches/102-perf-unpack-Use-memory-mapping-to-reduce-memory-usag.patch new file mode 100644 index 00000000..530cc15e --- /dev/null +++ b/v2dat/patches/102-perf-unpack-Use-memory-mapping-to-reduce-memory-usag.patch @@ -0,0 +1,128 @@ +From 0c6f9a36049423283052dfaf6eb9e211afe95c89 Mon Sep 17 00:00:00 2001 +From: sbwml +Date: Fri, 20 Mar 2026 10:11:24 +0800 +Subject: [PATCH 3/3] perf(unpack): Use memory mapping to reduce memory usage + +Replaced `os.ReadFile` with `mmap` to avoid loading the entire geoip.dat +or geosite.dat file into memory during unpacking. This fixes +out-of-memory errors on low-memory devices. + +Signed-off-by: sbwml +--- + cmd/unpack/geoip.go | 18 ++++++++++++++---- + cmd/unpack/geosite.go | 11 ++++++++++- + go.mod | 4 +++- + go.sum | 4 ++++ + 4 files changed, 31 insertions(+), 6 deletions(-) + +--- a/cmd/unpack/geoip.go ++++ b/cmd/unpack/geoip.go +@@ -3,14 +3,16 @@ package unpack + import ( + "bufio" + "fmt" +- "github.com/spf13/cobra" +- "github.com/urlesistiana/v2dat/v2data" +- "go.uber.org/zap" + "io" + "net/netip" + "os" + "path/filepath" + "strings" ++ ++ "github.com/edsrzf/mmap-go" ++ "github.com/spf13/cobra" ++ "github.com/urlesistiana/v2dat/v2data" ++ "go.uber.org/zap" + ) + + func newGeoIPCmd() *cobra.Command { +@@ -34,10 +36,18 @@ func newGeoIPCmd() *cobra.Command { + + func unpackGeoIP(args *unpackArgs) error { + filePath, wantTags, ourDir := args.file, args.filters, args.outDir +- b, err := os.ReadFile(filePath) ++ ++ file, err := os.Open(filePath) + if err != nil { + return err + } ++ defer file.Close() ++ ++ b, err := mmap.Map(file, mmap.RDONLY, 0) ++ if err != nil { ++ return fmt.Errorf("error mapping file: %w", err) ++ } ++ defer b.Unmap() + geoIPList, err := v2data.LoadGeoIPListFromDAT(b) + if err != nil { + return err +--- a/cmd/unpack/geosite.go ++++ b/cmd/unpack/geosite.go +@@ -3,6 +3,7 @@ package unpack + import ( + "bufio" + "fmt" ++ "github.com/edsrzf/mmap-go" + "github.com/spf13/cobra" + "github.com/urlesistiana/v2dat/v2data" + "go.uber.org/zap" +@@ -39,10 +40,18 @@ func newGeoSiteCmd() *cobra.Command { + + func unpackGeoSite(args *unpackArgs) error { + filePath, suffixes, outDir := args.file, args.filters, args.outDir +- b, err := os.ReadFile(filePath) ++ ++ file, err := os.Open(filePath) + if err != nil { + return err + } ++ defer file.Close() ++ ++ b, err := mmap.Map(file, mmap.RDONLY, 0) ++ if err != nil { ++ return fmt.Errorf("error mapping file: %w", err) ++ } ++ defer b.Unmap() + geoSiteList, err := v2data.LoadGeoSiteList(b) + if err != nil { + return err +--- a/go.mod ++++ b/go.mod +@@ -1,8 +1,9 @@ + module github.com/urlesistiana/v2dat + +-go 1.23 ++go 1.25.0 + + require ( ++ github.com/edsrzf/mmap-go v1.2.0 + github.com/spf13/cobra v1.10.2 + go.uber.org/zap v1.27.1 + google.golang.org/protobuf v1.36.11 +@@ -12,4 +13,5 @@ require ( + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/spf13/pflag v1.0.10 // indirect + go.uber.org/multierr v1.11.0 // indirect ++ golang.org/x/sys v0.42.0 // indirect + ) +--- a/go.sum ++++ b/go.sum +@@ -1,6 +1,8 @@ + github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= + github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= + github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= ++github.com/edsrzf/mmap-go v1.2.0 h1:hXLYlkbaPzt1SaQk+anYwKSRNhufIDCchSPkUD6dD84= ++github.com/edsrzf/mmap-go v1.2.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q= + github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= + github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= + github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +@@ -22,6 +24,8 @@ go.uber.org/multierr v1.11.0/go.mod h1:2 + go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= + go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= + go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= ++golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= ++golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= + google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= + google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= + gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=