update 2026-10-17 22:50:00

This commit is contained in:
action committed 2026-10-17 22:50:00 +08:00
1 parent 63dbfd1d1b
commit b9c5dc7236
19 files changed
+262 -131

No files matched your search

+1 -1
View File
@@ -22,7 +22,7 @@ PKG_NAME:=luci-app-amlogic
# DD = day (01 = 1st)
# NN = daily release sequence (01 = first release of the day, 02 = second, ...)
# Example below: 26.10.0101 = October 1, 2026, 1st release of the day
PKG_VERSION:=26.10.1501
PKG_VERSION:=26.10.1603
# PKG_RELEASE marks the LuCI variant; onekey-install.sh relies on it (do NOT bump)
# 1 = Lua version (lua branch) → tag: 26.10.0101
# 2 = JS version (main branch) → tag: 26.10.0101-js
@@ -43,7 +43,6 @@ return view.extend({
const m = new form.Map('amlogic', _('CPU Freq Settings'),
_('Set CPU Scaling Governor to Max Performance or Balance Mode'));
const s = m.section(form.NamedSection, 'armcpu', 'settings');
s.anonymous = true;
// Render an independent tab + form options per CPU cluster (big/little).
policies.forEach(function (p) {
@@ -17,7 +17,7 @@ const callPlatform = rpc.declare({ object: 'luci.amlogic', method: 'platform_inf
// Query runtime state; kernel_release is used to derive default kernel tag and branch.
const callState = rpc.declare({ object: 'luci.amlogic', method: 'state' });
// This page uses its own Save button; hide LuCI's default Save/Apply/Reset.
// Saves go through LuCI's default footer buttons (Save & Apply / Save / Reset).
return view.extend({
// Load platform info + state in parallel, along with the UCI config (we will read/write it).
load: function () {
@@ -43,7 +43,17 @@ return view.extend({
_('You can customize the github.com download repository of OpenWrt files and kernels in [Online Download Update].') +
'<br />' + _('Tip: The same files as the current OpenWrt system\'s BOARD (such as rock5b) and kernel (such as 5.10) will be downloaded.'));
const o = m.section(form.NamedSection, 'config', 'amlogic');
o.anonymous = true;
// Load the derived default ourselves whenever the stored value is blank.
const orDefault = function (option, defval) {
option.default = defval;
option.load = function (section_id) {
const v = uci.get(this.uciconfig ?? 'amlogic',
this.ucisection ?? section_id,
this.ucioption ?? this.option);
return (v == null || v === '') ? defval : v;
};
};
// 1. Display device platform
const dev = o.option(form.DummyValue, 'mydevice', _('Current Device:'),
@@ -73,10 +83,11 @@ return view.extend({
suffix.rmempty = false;
// 5. Kernel download repository
const kpath = o.option(form.ListValue, 'amlogic_kernel_path',
const kpath = o.option(form.Value, 'amlogic_kernel_path',
_('Kernel download repository:'),
_('Set the kernel files download repository on github.com in [Online Download Update].'));
kpath.value('https://github.com/ophub/kernel');
kpath.value('https://github.com/breakingbadboy/OpenWrt');
kpath.default = 'https://github.com/ophub/kernel';
kpath.rmempty = false;
@@ -93,32 +104,38 @@ return view.extend({
knownTags.kernel_flippy = 'kernel_flippy [Mainline Stable Kernel by Flippy]';
knownTags.kernel_beta = 'kernel_beta [Beta Kernel]';
}
// Determine default tag from saved config or kernel_release uname string.
let kernelTagDefault = uci.get('amlogic', 'config', 'amlogic_kernel_tags') || '';
if (!kernelTagDefault) {
const u = state.kernel_release || '';
if (u.indexOf('-rk3588') >= 0) kernelTagDefault = 'kernel_rk3588';
else if (u.indexOf('-rk35xx') >= 0) kernelTagDefault = 'kernel_rk35xx';
else if (u.indexOf('-beta') >= 0) kernelTagDefault = 'kernel_beta';
else kernelTagDefault = 'kernel_stable';
}
const ktags = o.option(form.ListValue, 'amlogic_kernel_tags',
// Derive the default tag from the kernel_release uname string. A value already
// saved in UCI wins; orDefault() below only kicks in when that value is blank.
const uname = state.kernel_release || '';
let kernelTagDefault = 'kernel_stable';
if (uname.indexOf('-rk3588') >= 0) kernelTagDefault = 'kernel_rk3588';
else if (uname.indexOf('-rk35xx') >= 0) kernelTagDefault = 'kernel_rk35xx';
else if (uname.indexOf('-beta') >= 0) kernelTagDefault = 'kernel_beta';
const ktags = o.option(form.Value, 'amlogic_kernel_tags',
_('Kernel download tags:'),
_('Set the kernel files download tags on github.com in [Online Download Update].'));
Object.keys(knownTags).forEach(function (k) { ktags.value(k, _(knownTags[k])); });
// kernel_beta is only offered for ophub/kernel, but a beta kernel may still be
// running, so keep the derived value selectable even when it is not listed.
if (!knownTags[kernelTagDefault]) ktags.value(kernelTagDefault, kernelTagDefault);
ktags.default = kernelTagDefault;
orDefault(ktags, kernelTagDefault);
ktags.rmempty = false;
// 7. Kernel branch
const kbranch = o.option(form.ListValue, 'amlogic_kernel_branch',
const kbranches = ['5.10', '5.15', '6.1', '6.6', '6.12', '6.18'];
const kbranch = o.option(form.Value, 'amlogic_kernel_branch',
_('Set version branch:'),
_('Set the version branch of the OpenWrt files and kernel selected in [Online Download Update].'));
['5.10', '5.15', '6.1', '6.6', '6.12', '6.18'].forEach(function (b) {
kbranch.value(b, _(b));
// Extract the major.minor version from the kernel uname string to determine the default branch.
const km = uname.match(/^(\d+\.\d+)/);
const kbranchDefault = km ? km[1] : kbranches[0];
// If the derived default branch is not in the list, add it so it can be selected.
if (kbranches.indexOf(kbranchDefault) < 0) kbranches.push(kbranchDefault);
kbranches.forEach(function (b) {
kbranch.value(b, b);
});
const m2 = (state.kernel_release || '').match(/^(\d+\.\d+)/);
kbranch.default = m2 ? m2[1] : '5.10';
orDefault(kbranch, kbranchDefault);
kbranch.rmempty = false;
// 8. Plugin branch
@@ -140,14 +157,14 @@ return view.extend({
fcfg.default = '1';
fcfg.rmempty = false;
// 9. Write bootloader
// 10. Write bootloader
const wb = o.option(form.Flag, 'amlogic_write_bootloader',
_('Auto write bootloader:'),
_('[Recommended choice] Set whether to auto write bootloader during install and update OpenWrt.'));
wb.default = '0';
wb.rmempty = false;
// 10. Shared partition fs type
// 11. Shared partition fs type
const fst = o.option(form.ListValue, 'amlogic_shared_fstype',
_('Set the file system type:'),
_('[Default ext4] Set the file system type of the shared partition (/mnt/mmcblk*p4) when install OpenWrt.'));
@@ -1814,9 +1814,6 @@ stop() {
[ -n "${bak_bridge_nf_ip6t}" ] && sysctl -w net.bridge.bridge-nf-call-ip6tables=${bak_bridge_nf_ip6t} >/dev/null 2>&1
}
rm -rf $TMP_PATH
rm -f ${LOCK_PATH}/${CONFIG}_socks_auto_switch*
rm -f ${LOCK_PATH}/${CONFIG}_lease2hosts*
rm -f ${LOCK_PATH}/${CONFIG}_monitor*
echolog "清空并关闭相关程序和缓存完成。"
exit 0
}
@@ -93,6 +93,6 @@ while true; do
rm -f "$TMP_FILE"
fi
sleep 60
sleep 60 9>&-
done 2>/dev/null
@@ -498,6 +498,16 @@ if singbox_tags:find("with_quic") then
o = s:option(Value, "hysteria2_down_mbps", translate("Max download Mbps"))
o:depends({ protocol = "hysteria2" })
o = s:option(Value, "hysteria2_stream_recv_win", translate("QUIC stream receive window") .. " (MB)")
o.datatype = "range(1,1000)"
o.placeholder = "8"
o:depends({ protocol = "hysteria2" })
o = s:option(Value, "hysteria2_conn_recv_win", translate("QUIC connection receive window") .. " (MB)")
o.datatype = "range(1,1000)"
o.placeholder = "20"
o:depends({ protocol = "hysteria2" })
o = s:option(Value, "hysteria2_idle_timeout", translate("Idle Timeout"), translate("Units:seconds") .. " (4~120)")
o.datatype = "range(4,120)"
o:depends({ protocol = "hysteria2"})
@@ -403,6 +403,16 @@ o:depends({ protocol = "hysteria2" })
o = s:option(Value, "hysteria2_down_mbps", translate("Max download Mbps"))
o:depends({ protocol = "hysteria2" })
o = s:option(Value, "hysteria2_stream_recv_win", translate("QUIC stream receive window") .. " (MB)")
o.datatype = "range(1,1000)"
o.placeholder = "8"
o:depends({ protocol = "hysteria2" })
o = s:option(Value, "hysteria2_conn_recv_win", translate("QUIC connection receive window") .. " (MB)")
o.datatype = "range(1,1000)"
o.placeholder = "20"
o:depends({ protocol = "hysteria2" })
o = s:option(Value, "hysteria2_idle_timeout", translate("Idle Timeout"), translate("Units:seconds") .. " (4~120)")
o.datatype = "range(4,120)"
o:depends({ protocol = "hysteria2"})
+4 -3
View File
@@ -449,9 +449,10 @@ function repeat_exist(table, value)
end
function remove(...)
for index, value in ipairs({...}) do
if value and #value > 0 and value ~= "/" then
sys.call(string.format("rm -rf %s", value))
for i = 1, select("#", ...) do
local value = select(i, ...)
if type(value) == "string" and #value > 0 and value ~= "/" then
sys.call(string.format("rm -rf -- %s", value))
end
end
end
@@ -635,7 +635,9 @@ function gen_outbound(flag, node, tag, proxy_table)
t = tonumber(tostring(t or "0"):match("^%d+"))
return (t and t >= 2 and t <= 60) and t .. "s" or nil
end)(node.hysteria2_keep_alive_period),
disable_path_mtu_discovery = version_ge_1_14_0 and (tonumber(node.hysteria2_disable_mtu_discovery) == 1) or nil,
stream_receive_window = tonumber(node.hysteria2_stream_recv_win) and tonumber(node.hysteria2_stream_recv_win) .. " MB" or nil,
connection_receive_window = tonumber(node.hysteria2_conn_recv_win) and tonumber(node.hysteria2_conn_recv_win) .. " MB" or nil,
disable_path_mtu_discovery = version_ge_1_14_0 and (node.hysteria2_disable_mtu_discovery == "1") or nil,
tls = tls,
realm = node.hysteria2_realms and (function()
result.server = nil
@@ -400,7 +400,9 @@ function gen_outbound(flag, node, tag, proxy_table)
t = tonumber(tostring(t or "0"):match("^%d+"))
return (t and t >= 2 and t <= 60) and t or nil
end)(node.hysteria2_keep_alive_period),
disablePathMTUDiscovery = tonumber(node.hysteria2_disable_mtu_discovery) == 1
disablePathMTUDiscovery = node.hysteria2_disable_mtu_discovery == "1",
initStreamReceiveWindow = tonumber(node.hysteria2_stream_recv_win) and tonumber(node.hysteria2_stream_recv_win)*1048576 or nil,
initConnectionReceiveWindow = tonumber(node.hysteria2_conn_recv_win) and tonumber(node.hysteria2_conn_recv_win)*1048576 or nil,
}
end
if fragment and fragment_table and ({raw=1, ws=1, httpupgrade=1, grpc=1, xhttp=1})[TP] then
+11 -2
View File
@@ -2219,8 +2219,14 @@ msgstr "تشخیص تغییر وضعیت سوکت‌ها: تغییر وضعیت
msgid "Socks switch detection: Port [%s] [%s:[%s]] abnormal."
msgstr "تشخیص وضعیت سوئیچ: پورت [%s] [%s:[%s]] غیرعادی است."
msgid "Socks switch detection: Port [%s] all nodes are unavailable!"
msgstr "تشخیص تغییر وضعیت سوئیچ: در پورت [%s]، تمام گره‌ها در دسترس نیستند!"
msgid "Socks switch detection: Port [%s] all nodes are unavailable or switching failed!"
msgstr "بررسی تغییر گره SOCKS: پورت [%s]، همه گره‌ها در دسترس نیستند یا تغییر گره ناموفق بود!"
msgid "Socks switch detection: Port [%s] node switch failed, continue trying other nodes!"
msgstr "بررسی تغییر گره SOCKS: پورت [%s]، تغییر گره ناموفق بود؛ تلاش با گره‌های دیگر ادامه دارد!"
msgid "Socks switch detection: Port [%s] failed to restore the primary node!"
msgstr "بررسی تغییر گره SOCKS: پورت [%s]، بازیابی گره اصلی ناموفق بود!"
msgid "Socks switch detection: Port [%s] Unknown error."
msgstr "تشخیص وضعیت سوئیچ جوراب: پورت [%s] خطای ناشناخته."
@@ -2486,6 +2492,9 @@ msgstr "فهرست مجموعه‌های رمز پشتیبانی‌شده را
msgid "This username already exists."
msgstr "این نام کاربری از قبل وجود دارد."
msgid "Update Options"
msgstr "گزینه‌های به‌روزرسانی"
msgid "MASQUE Path"
msgstr "مسیر MASQUE"
+11 -2
View File
@@ -2220,8 +2220,14 @@ msgstr "Обнаружение переключения соединений: п
msgid "Socks switch detection: Port [%s] [%s:[%s]] abnormal."
msgstr "Обнаружено переключение Socks: порт [%s] [%s:[%s]] работает некорректно."
msgid "Socks switch detection: Port [%s] all nodes are unavailable!"
msgstr "Обнаружено переключение коммутатора: порт [%s], все узлы недоступны!"
msgid "Socks switch detection: Port [%s] all nodes are unavailable or switching failed!"
msgstr "Проверка переключения SOCKS: порт [%s], все узлы недоступны или переключение не удалось!"
msgid "Socks switch detection: Port [%s] node switch failed, continue trying other nodes!"
msgstr "Проверка переключения SOCKS: порт [%s], переключить узел не удалось, пробуем другие узлы!"
msgid "Socks switch detection: Port [%s] failed to restore the primary node!"
msgstr "Проверка переключения SOCKS: порт [%s], не удалось восстановить основной узел!"
msgid "Socks switch detection: Port [%s] Unknown error."
msgstr "Обнаружение переключения разъема: порт [%s], неизвестная ошибка."
@@ -2487,6 +2493,9 @@ msgstr "Задает список поддерживаемых наборов ш
msgid "This username already exists."
msgstr "Это имя пользователя уже существует."
msgid "Update Options"
msgstr "Параметры обновления"
msgid "MASQUE Path"
msgstr "Путь MASQUE"
+8 -2
View File
@@ -2205,8 +2205,14 @@ msgstr "Socks切换检测:端口 [%s] 节点切换完毕!"
msgid "Socks switch detection: Port [%s] [%s:[%s]] abnormal."
msgstr "Socks切换检测:端口 [%s] 异常。"
msgid "Socks switch detection: Port [%s] all nodes are unavailable!"
msgstr "Socks切换检测:端口 [%s] 所有节点均不可用!"
msgid "Socks switch detection: Port [%s] all nodes are unavailable or switching failed!"
msgstr "Socks切换检测:端口 [%s] 所有节点均不可用或切换失败!"
msgid "Socks switch detection: Port [%s] node switch failed, continue trying other nodes!"
msgstr "Socks切换检测:端口 [%s] 节点切换失败,继续尝试其他节点!"
msgid "Socks switch detection: Port [%s] failed to restore the primary node!"
msgstr "Socks切换检测:端口 [%s] 恢复主节点失败!"
msgid "Socks switch detection: Port [%s] Unknown error."
msgstr "Socks切换检测:端口 [%s] 未知错误。"
+11 -2
View File
@@ -2211,8 +2211,14 @@ msgstr "Socks切換偵測:連接埠 [%s] 節點切換完畢!"
msgid "Socks switch detection: Port [%s] [%s:[%s]] abnormal."
msgstr "Socks切換偵測:連接埠 [%s] 異常。"
msgid "Socks switch detection: Port [%s] all nodes are unavailable!"
msgstr "Socks切換偵測:連接埠 [%s] 所有節點均不可用!"
msgid "Socks switch detection: Port [%s] all nodes are unavailable or switching failed!"
msgstr "Socks切換偵測:連接埠 [%s] 所有節點均不可用或切換失敗!"
msgid "Socks switch detection: Port [%s] node switch failed, continue trying other nodes!"
msgstr "Socks切換偵測:連接埠 [%s] 節點切換失敗,繼續嘗試其他節點!"
msgid "Socks switch detection: Port [%s] failed to restore the primary node!"
msgstr "Socks切換偵測:連接埠 [%s] 恢復主節點失敗!"
msgid "Socks switch detection: Port [%s] Unknown error."
msgstr "Socks切換偵測:連接埠 [%s] 未知錯誤。"
@@ -2478,6 +2484,9 @@ msgstr "配置支援的密碼套件列表。"
msgid "This username already exists."
msgstr "該用戶名已存在。"
msgid "Update Options"
msgstr "更新選項"
msgid "MASQUE Path"
msgstr "MASQUE 路徑"
@@ -380,7 +380,7 @@ run_socks() {
if [ -n "$server_host" ] && [ -n "$server_port" ]; then
check_host $server_host
[ $? != 0 ] && {
log 1 "$(i18n "Socks node: [%s]%s is an invalid server address and cannot be started!" "${$remarks}" "${server_host}")"
log 1 "$(i18n "Socks node: [%s]%s is an invalid server address and cannot be started!" "${remarks}" "${server_host}")"
return 1
}
tmp="${server_host}:${server_port}"
@@ -553,9 +553,12 @@ socks_node_switch() {
local http_config_file="${flag}_http.json"
LOG_FILE="/dev/null"
run_socks flag=$flag node=$new_node bind=$bind socks_port=$port config_file=$config_file http_port=$http_port http_config_file=$http_config_file log_file=$log_file
sleep 2s
[ "$(check_port_exists "$port" tcp)" = "0" ] && return 1
set_cache_var "${flag}" "$new_node"
local USE_TABLES=$(get_cache_var "USE_TABLES")
[ -n "$USE_TABLES" ] && source $APP_PATH/${USE_TABLES}.sh filter_direct_node_list
return 0
}
}
@@ -579,11 +582,15 @@ start_socks() {
[ "$log" == "0" ] && log_file=""
local http_port=$(config_n_get $id http_port 0)
local http_config_file="${id}_http.json"
run_socks flag=$id node=$node bind=$bind socks_port=$port config_file=$config_file http_port=$http_port http_config_file=$http_config_file log_file=$log_file
local enable_autoswitch=$(config_n_get $id enable_autoswitch 0)
if [ "$enable_autoswitch" = "1" ]; then
NO_REC_PROCESS=1 $APP_PATH/app.sh run_socks flag=$id node=$node bind=$bind socks_port=$port config_file=$config_file http_port=$http_port http_config_file=$http_config_file log_file=$log_file
else
run_socks flag=$id node=$node bind=$bind socks_port=$port config_file=$config_file http_port=$http_port http_config_file=$http_config_file log_file=$log_file
fi
set_cache_var "${id}" "$node"
# Auto switch logic
local enable_autoswitch=$(config_n_get $id enable_autoswitch 0)
[ "$enable_autoswitch" = "1" ] && { $APP_PATH/socks_auto_switch.sh ${id} > /dev/null 2>&1 & }
done
}
@@ -619,6 +626,9 @@ start_crontab() {
return
}
local setsid_cmd=""
command -v setsid >/dev/null 2>&1 && setsid_cmd="setsid "
stop_week_mode=$(config_n_get @global_delay[0] stop_week_mode)
stop_time_mode=$(config_n_get @global_delay[0] stop_time_mode)
if [ -n "$stop_week_mode" ]; then
@@ -626,7 +636,7 @@ start_crontab() {
stop_time_mm=$(echo $stop_time_mode | awk -F ':' '{print $2}')
local t="$stop_time_mm $stop_time_hh * * $stop_week_mode"
[ "$stop_week_mode" = "7" ] && t="$stop_time_mm $stop_time_hh * * *"
echo "$t /etc/init.d/$CONFIG stop cron > /dev/null 2>&1 &" >>/etc/crontabs/root
echo "$t ${setsid_cmd}/etc/init.d/$CONFIG stop cron > /dev/null 2>&1 &" >>/etc/crontabs/root
log_i18n 0 "Scheduled tasks: Auto stop service."
fi
@@ -637,7 +647,7 @@ start_crontab() {
start_time_mm=$(echo $start_time_mode | awk -F ':' '{print $2}')
local t="$start_time_mm $start_time_hh * * $start_week_mode"
[ "$start_week_mode" = "7" ] && t="$start_time_mm $start_time_hh * * *"
echo "$t /etc/init.d/$CONFIG start cron > /dev/null 2>&1 &" >>/etc/crontabs/root
echo "$t ${setsid_cmd}/etc/init.d/$CONFIG start cron > /dev/null 2>&1 &" >>/etc/crontabs/root
log_i18n 0 "Scheduled tasks: Auto start service."
fi
@@ -651,7 +661,7 @@ start_crontab() {
if [ "$restart_week_mode" = "8" ]; then
update_loop=1
else
echo "$t /etc/init.d/$CONFIG restart cron > /dev/null 2>&1 &" >>/etc/crontabs/root
echo "$t ${setsid_cmd}/etc/init.d/$CONFIG restart cron > /dev/null 2>&1 &" >>/etc/crontabs/root
fi
log_i18n 0 "Scheduled tasks: Auto restart service."
fi
@@ -666,7 +676,7 @@ start_crontab() {
if [ "$rules_update_week_mode" = "8" ]; then
update_loop=1
else
echo "$t lua $APP_PATH/rule_update.lua log all cron > /dev/null 2>&1 &" >>/etc/crontabs/root
echo "$t ${setsid_cmd}lua $APP_PATH/rule_update.lua log all cron > /dev/null 2>&1 &" >>/etc/crontabs/root
fi
log_i18n 0 "Scheduled tasks: Auto update rules."
fi
@@ -695,7 +705,7 @@ start_crontab() {
if [ "$sub_update_week_mode" = "8" ]; then
update_loop=1
else
echo "$t lua $APP_PATH/subscribe.lua start $cfgids cron > /dev/null 2>&1 &" >>/etc/crontabs/root
echo "$t ${setsid_cmd}lua $APP_PATH/subscribe.lua start $cfgids cron > /dev/null 2>&1 &" >>/etc/crontabs/root
fi
done
rm -rf $TMP_SUB_PATH
@@ -996,8 +1006,6 @@ stop() {
[ -n "${bak_bridge_nf_ip6t}" ] && sysctl -w net.bridge.bridge-nf-call-ip6tables=${bak_bridge_nf_ip6t} >/dev/null 2>&1
}
rm -rf $TMP_PATH
rm -f ${LOCK_PATH}/${CONFIG}_socks_auto_switch*
rm -f ${LOCK_PATH}/${CONFIG}_lease2hosts*
rm -f ${LOCK_PATH}/${CONFIG}_monitor*
log_i18n 0 "Clearing and closing related programs and cache complete."
exit 0
@@ -1,17 +1,61 @@
#!/bin/sh
# dhcp.leases to hosts
# DHCP leases and static hosts to hosts
. /lib/functions.sh
. /usr/share/passwall2/utils.sh
LOCK_FILE=${LOCK_PATH}/${CONFIG}_lease2hosts.lock
LEASE_FILE=$(uci -q get dhcp.@dnsmasq[0].leasefile || echo "/tmp/dhcp.leases")
DNSMASQ_LEASE_FILE=$(uci -q get 'dhcp.@dnsmasq[0].leasefile')
DNSMASQ_LEASE_FILE=${DNSMASQ_LEASE_FILE:-/tmp/dhcp.leases}
ODHCPD_LEASE_FILE=$(uci -q get dhcp.odhcpd.leasefile)
ODHCPD_LEASE_FILE=${ODHCPD_LEASE_FILE:-/tmp/odhcpd.leases}
HOSTS_FILE="$TMP_PATH2/dhcp-hosts"
TMP_FILE="/tmp/dhcp-hosts.tmp"
exec 99>"$LOCK_FILE"
flock -n 99
if [ "$?" != 0 ]; then
exit 0
fi
exec 9>"$LOCK_FILE"
flock -n 9 || exit 0
read_static_host() {
local name ip
config_get name "$1" name
config_get ip "$1" ip
[ -n "$name" ] && [ "$name" != "*" ] && [ -n "$ip" ] && [ "$ip" != "ignore" ] || return
printf '%s %s\n' "$ip" "$name"
}
# Static DHCP configuration only needs to be read once at startup.
STATIC_HOSTS=$(
config_load dhcp
config_foreach read_static_host host
)
read_odhcpd_leases() {
[ -f "$ODHCPD_LEASE_FILE" ] || return
awk -v now="$(date +%s)" '
function valid_name(name) {
return name ~ /^[a-zA-Z0-9_][a-zA-Z0-9_.-]*$/
}
# State records: # interface DUID IAID hostname expiry assigned length address/prefix ...
$1 == "#" {
if (NF < 9 || !valid_name($5) || ($6 != -1 && $6 <= now))
next
# Only host addresses, never delegated IPv6 prefixes.
if (!(($4 == "ipv4" && $8 == 32) || ($4 != "ipv4" && $8 == 128)))
next
for (i = 9; i <= NF; i++) {
split($i, addr, "/")
print addr[1] " " $5
}
next
}
# Older odhcpd versions also include hosts-format lines, with optional aliases.
NF >= 2 && $1 ~ /^[0-9a-fA-F:.]+$/ {
for (i = 2; i <= NF && $i !~ /^#/; i++)
if (valid_name($i))
print $1 " " $i
}
' "$ODHCPD_LEASE_FILE"
}
reload_dnsmasq_pids() {
local pidfile pid
@@ -27,24 +71,28 @@ reload_dnsmasq_pids() {
while true; do
if [ -f "$LEASE_FILE" ]; then
awk 'NF >= 4 && $4 != "*" {print $3" "$4}' "$LEASE_FILE" | sort > "$TMP_FILE"
if [ -s "$TMP_FILE" ]; then
if [ ! -f "$HOSTS_FILE" ] || ! cmp -s "$TMP_FILE" "$HOSTS_FILE"; then
mv "$TMP_FILE" "$HOSTS_FILE"
reload_dnsmasq_pids
else
rm -f "$TMP_FILE"
fi
{
[ -n "$STATIC_HOSTS" ] && printf '%s\n' "$STATIC_HOSTS"
if [ -f "$DNSMASQ_LEASE_FILE" ]; then
awk 'NF >= 4 && $4 != "*" {print $3" "$4}' "$DNSMASQ_LEASE_FILE"
fi
read_odhcpd_leases
} | sort -u > "$TMP_FILE"
if [ -s "$TMP_FILE" ]; then
if [ ! -f "$HOSTS_FILE" ] || ! cmp -s "$TMP_FILE" "$HOSTS_FILE"; then
mv "$TMP_FILE" "$HOSTS_FILE"
reload_dnsmasq_pids
else
if [ -s "$HOSTS_FILE" ]; then
: > "$HOSTS_FILE"
reload_dnsmasq_pids
fi
rm -f "$TMP_FILE"
fi
else
if [ -s "$HOSTS_FILE" ]; then
: > "$HOSTS_FILE"
reload_dnsmasq_pids
fi
rm -f "$TMP_FILE"
fi
sleep 60
sleep 60 9>&-
done 2>/dev/null
@@ -3,11 +3,9 @@
. /usr/share/passwall2/utils.sh
APP_FILE=${APP_PATH}/app.sh
flag=0
check_process() {
while busybox pgrep -af "${CONFIG}/" | grep -E 'app\.sh.*(start|stop)|nftables\.sh|iptables\.sh|subscribe\.lua' >/dev/null; do
sleep 6s
sleep 6s 8>&- 9>&-
done
}
@@ -25,19 +23,21 @@ test_url() {
fi
[ "$curl_retry_all_errors" = "1" ] && extra_params="--retry-all-errors ${extra_params}"
local max_time=$((timeout * (try + 1) + try + 3))
local max_time=$((timeout + 3))
local retry_max_time=$((max_time * (try + 1) + try))
curl_test() {
/usr/bin/curl -skIL -o /dev/null ${extra_params} --max-time ${max_time} --connect-timeout ${timeout} --retry ${try} --retry-delay 1 -w "%{http_code}" "$url"
/usr/bin/curl -skIL -o /dev/null ${extra_params} --max-time ${max_time} --connect-timeout ${timeout} --retry ${try} --retry-delay 1 --retry-max-time ${retry_max_time} -w "%{http_code}" "$url" 8>&- 9>&-
}
local status=$(curl_test)
local status
status=$(curl_test) || status=000
[ "$status" = "204" ] && status=200
if [ "$status" = "200" ] && [ "$repeat" = "1" ]; then
sleep 3s
status=$(curl_test)
sleep 3s 8>&- 9>&-
status=$(curl_test) || status=000
[ "$status" = "204" ] && status=200
fi
echo $status
printf '%s' "$status"
}
test_proxy() {
@@ -51,7 +51,7 @@ test_proxy() {
result=1
else
result=2
ping -c 3 -W 1 223.5.5.5 > /dev/null 2>&1
ping -c 3 -W 1 223.5.5.5 > /dev/null 2>&1 8>&- 9>&-
[ $? -eq 0 ] && {
result=1
}
@@ -62,24 +62,31 @@ test_proxy() {
test_node() {
local node_id=$1
local _type=$(echo $(config_n_get ${node_id} type) | tr 'A-Z' 'a-z')
[ -n "${_type}" ] && {
check_process
local _tmp_port=$(get_new_port 48800 tcp,udp)
NO_REC_PROCESS=1 $APP_FILE run_socks flag="test_node_${node_id}" node=${node_id} bind=127.0.0.1 socks_port=${_tmp_port} config_file=test_node_${node_id}.json
sleep 2s
local curlx="socks5h://127.0.0.1:${_tmp_port}"
local _proxy_status=$(test_url "${probe_url}" ${retry_num} ${connect_timeout} "-x $curlx" 1)
# Kill the SS plugin process
local pid_file="${TMP_PATH}/test_node_${node_id}_plugin.pid"
[ -s "$pid_file" ] && kill -9 "$(head -n 1 "$pid_file")" >/dev/null 2>&1
busybox pgrep -af "test_node_${node_id}" | awk '! /socks_auto_switch\.sh/{print $1}' | xargs kill -9 >/dev/null 2>&1
rm -rf ${TMP_PATH}/test_node_${node_id}*.*
if [ "${_proxy_status}" -eq 200 ]; then
return 0
fi
}
return 1
local test_flag="test_node_${id}_${node_id}"
local _type _tmp_port curlx _proxy_status pid_file
(
exec 9>&-
exec 8>"${LOCK_PATH}/${CONFIG}_socks_auto_switch_test.lock"
flock -x 8 || exit 1
_type=$(echo $(config_n_get ${node_id} type) | tr 'A-Z' 'a-z')
[ -n "${_type}" ] && {
check_process
_tmp_port=$(get_new_port 48800 tcp,udp) || exit 1
NO_REC_PROCESS=1 "$APP_FILE" run_socks flag="$test_flag" node="$node_id" bind=127.0.0.1 socks_port="$_tmp_port" config_file="${test_flag}.json" 8>&- 9>&-
sleep 2s 8>&- 9>&-
curlx="socks5h://127.0.0.1:${_tmp_port}"
_proxy_status=$(test_url "${probe_url}" ${retry_num} ${connect_timeout} "-x $curlx" 1)
# Kill the SS plugin process.
pid_file="${TMP_PATH}/${test_flag}_plugin.pid"
[ -s "$pid_file" ] && kill -9 "$(head -n 1 "$pid_file")" >/dev/null 2>&1
busybox pgrep -af "${TMP_PATH}/${test_flag}[._]" | awk '! /socks_auto_switch\.sh/{print $1}' | xargs -r kill -9 >/dev/null 2>&1
rm -f "$TMP_PATH/${test_flag}"*.*
if [ "${_proxy_status}" -eq 200 ]; then
exit 0
fi
}
exit 1
)
}
try_switch_backup() {
@@ -122,23 +129,23 @@ try_switch_backup() {
if test_node ${new_node}; then
check_process
log_i18n 0 "Socks switch detection: Port [%s] [%s:[%s]] normal, switch to this node!" "${socks_port}" "${node_type}" "${node_remarks}"
NO_REC_PROCESS=1 $APP_FILE socks_node_switch flag=${id} new_node=${new_node}
[ $? -eq 0 ] && {
if NO_REC_PROCESS=1 "$APP_FILE" socks_node_switch flag="$id" new_node="$new_node" 9>&-; then
log_i18n 0 "Socks switch detection: Port [%s] node switch complete!" "${socks_port}"
}
return 0
return 0
fi
log_i18n 0 "Socks switch detection: Port [%s] node switch failed, continue trying other nodes!" "${socks_port}"
else
log_i18n 0 "Socks switch detection: Port [%s] [%s:[%s]] abnormal." "${socks_port}" "${node_type}" "${node_remarks}"
fi
log_i18n 0 "Socks switch detection: Port [%s] [%s:[%s]] abnormal." "${socks_port}" "${node_type}" "${node_remarks}"
now_node="$new_node"
tried=$((tried + 1))
done
log_i18n 0 "Socks switch detection: Port [%s] all nodes are unavailable!" "${socks_port}"
log_i18n 0 "Socks switch detection: Port [%s] all nodes are unavailable or switching failed!" "${socks_port}"
return 1
}
test_auto_switch() {
flag=$((flag + 1))
local b_nodes=$1
local now_node=$2
[ -z "$now_node" ] && {
@@ -150,9 +157,7 @@ test_auto_switch() {
fi
}
[ $flag -le 1 ] && main_node=$now_node
local status=$(test_proxy)
local status=$(test_proxy 9>&-)
if [ "$status" = "2" ]; then
log_i18n 0 "Socks switch detection: Port [%s] Unable to connect to the network. Please check if the network is working properly!" "${socks_port}"
return 2
@@ -163,13 +168,13 @@ test_auto_switch() {
test_node ${main_node}
[ $? -eq 0 ] && {
check_process
# The main node is working properly; switch to the main node.
log_i18n 0 "Socks switch detection: Port [%s] Primary node [%s: [%s]] is normal. Switch to the primary node!" "${socks_port}" "$(config_n_get $main_node type)" "$(config_n_get $main_node remarks)"
NO_REC_PROCESS=1 $APP_FILE socks_node_switch flag=${id} new_node=${main_node}
[ $? -eq 0 ] && {
if NO_REC_PROCESS=1 "$APP_FILE" socks_node_switch flag="$id" new_node="$main_node" 9>&-; then
log_i18n 0 "Socks switch detection: Port [%s] node switch complete!" "${socks_port}"
}
return 0
return 0
fi
log_i18n 0 "Socks switch detection: Port [%s] failed to restore the primary node!" "${socks_port}"
status=1
}
fi
@@ -186,6 +191,8 @@ test_auto_switch() {
start() {
id=$1
LOCK_FILE=${LOCK_PATH}/${CONFIG}_socks_auto_switch_${id}.lock
exec 9>"$LOCK_FILE"
flock -n 9 || return 0
main_node=$(config_n_get $id node)
socks_port=$(config_n_get $id port 0)
delay=$(config_n_get $id autoswitch_testing_time 30)
@@ -201,7 +208,10 @@ start() {
[ "$main_node" = "$backup_node" ] && return
elif [ "$backup_node_num" -gt 1 ]; then
[ "$restore_switch" != "1" ] && {
[ -z "$(echo $backup_node | grep -F "$main_node")" ] && backup_node="${backup_node} ${main_node}"
case " $backup_node " in
*" $main_node "*) ;;
*) backup_node="${backup_node} ${main_node}" ;;
esac
}
fi
else
@@ -209,15 +219,9 @@ start() {
return
fi
while [ -n "$backup_node" ]; do
[ -f "$LOCK_FILE" ] && {
sleep 6s
continue
}
check_process
touch $LOCK_FILE
test_auto_switch "$backup_node"
rm -f $LOCK_FILE
sleep ${delay}
sleep ${delay} 9>&-
done
}
@@ -2974,8 +2974,8 @@ start_rules() {
esac
}
if [ "$(uci_get_by_type global dports)" = "3" ]; then
custom_ports=$(uci_get_by_name "$GLOBAL_SERVER" custom_ports) # custom_ports 存储了用户自定义的端口
if [ "$(uci_get_by_type global dports 1)" = "3" ]; then
custom_ports=$(uci_get_by_type global custom_ports) # custom_ports 存储了用户自定义的端口
if [ -n "$custom_ports" ]; then
proxyport="-m multiport --dports $custom_ports"
fi
@@ -3017,7 +3017,7 @@ start_rules() {
-G "$(uci_get_by_type access_control lan_gm_ips)" \
-m "$(uci_get_by_type access_control Interface)" \
-D "$proxyport" \
"$(get_arg_out)" "$(gfwmode)" "$ARG_UDP" "$ARG_UDP_RULES" "$ARG_A"
$(get_arg_out) $(gfwmode) $ARG_UDP $ARG_UDP_RULES $ARG_A
return $?
}
+6 -6
View File
@@ -87,7 +87,7 @@ while [ "1" == "1" ]; do #死循环
#redir tcp
if [ "$redir_tcp_process" -gt 0 ]; then
icount=$(redir_tcp_running)
local tcp_expected="$redir_tcp_process"
tcp_expected="$redir_tcp_process"
if [ "$GLOBAL_TYPE" = "socks5" ]; then
tcp_expected="$EXPECTED_THREADS"
fi
@@ -101,7 +101,7 @@ while [ "1" == "1" ]; do #死循环
#redir udp
if [ "$redir_udp_process" -gt 0 ]; then
icount=$(redir_udp_running)
local udp_expected="$redir_udp_process"
udp_expected="$redir_udp_process"
if [ "$GLOBAL_TYPE" = "socks5" ]; then
udp_expected="$EXPECTED_THREADS"
fi
@@ -172,12 +172,12 @@ while [ "1" == "1" ]; do #死循环
echolog "chinadns-ng $dnsserver tunnel error.restart!"
dnsserver=$(uci_get_by_type global chinadns_ng_tunnel_forward 8.8.4.4:53)
kill -9 $(ps_list | grep "chinadns-ng -b 127.0.0.1 -l $tmp_dns_port" | grep -v grep | awk '{print $1}') >/dev/null 2>&1
local chinadns_ng_proto="$(uci_get_by_type global chinadns_ng_proto)"
local chinadns_ng_dns=""
chinadns_ng_proto="$(uci_get_by_type global chinadns_ng_proto)"
chinadns_ng_dns=""
IFS=','
for chinadns_ng_server in $dnsserver; do
local chinadns_ng_ip="${chinadns_ng_server%%:*}"
local chinadns_ng_port="${chinadns_ng_server##*:}"
chinadns_ng_ip="${chinadns_ng_server%%:*}"
chinadns_ng_port="${chinadns_ng_server##*:}"
[ "$chinadns_ng_ip" = "$chinadns_ng_port" ] && chinadns_ng_port="53"
chinadns_ng_tls_port="853"
case "$chinadns_ng_proto" in