mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-07-28 20:11:53 +08:00
185 lines
4.5 KiB
Bash
Executable File
185 lines
4.5 KiB
Bash
Executable File
#!/bin/sh /etc/rc.common
|
||
# iPerf3 Server init (OpenWrt 23.05) - procd multi-instance (UCI-only fetch)
|
||
# UCI: /etc/config/iperf3-server
|
||
#
|
||
# config iperf3-server
|
||
# option main_enable '1'
|
||
#
|
||
# config servers
|
||
# option enable_server '1'
|
||
# option port '5201'
|
||
# option delay '0'
|
||
# option extra_options ''
|
||
|
||
USE_PROCD=1
|
||
START=99
|
||
|
||
PROG="/usr/bin/iperf3"
|
||
CONFIG="iperf3-server"
|
||
LOGGER="logger -t iPerf3-Server"
|
||
|
||
# 与 CBI 的 extra_options 校验保持一致:拦截明显 shell 元字符
|
||
is_safe_extra_opts() {
|
||
[ -z "$1" ] && return 0
|
||
case "$1" in
|
||
*";"*|*"&"*|*"|"*|*"\`"*|*"\$"*|*"<"*|*">"*|*"\""*|*"'"* )
|
||
return 1
|
||
;;
|
||
esac
|
||
return 0
|
||
}
|
||
|
||
# 停止某端口:既杀 iperf3 server,也杀 delay 阶段的 sh/sleep
|
||
kill_by_port() {
|
||
local port="$1"
|
||
local pids
|
||
|
||
# 1) 已经起来的 iperf3 server
|
||
pids="$(ps w | grep '[i]perf3' | grep ' -s' | grep " -p $port" | awk '{print $1}')"
|
||
[ -n "$pids" ] && kill $pids 2>/dev/null
|
||
|
||
# 2) delay 阶段:/bin/sh -c "sleep N; exec iperf3 -s -p PORT ..."
|
||
pids="$(ps w | grep '[s]leep' | grep '[i]perf3' | grep " -p $port" | awk '{print $1}')"
|
||
[ -n "$pids" ] && kill $pids 2>/dev/null
|
||
|
||
sleep 1
|
||
|
||
# hard kill 兜底
|
||
pids="$(ps w | grep '[i]perf3' | grep ' -s' | grep " -p $port" | awk '{print $1}')"
|
||
[ -n "$pids" ] && kill -9 $pids 2>/dev/null
|
||
|
||
pids="$(ps w | grep '[s]leep' | grep '[i]perf3' | grep " -p $port" | awk '{print $1}')"
|
||
[ -n "$pids" ] && kill -9 $pids 2>/dev/null
|
||
}
|
||
|
||
# 获取 servers 索引列表(0 1 2 ...)
|
||
get_server_indexes() {
|
||
# 从 uci show 里提取 @servers[NUM]
|
||
uci -q show "$CONFIG" 2>/dev/null \
|
||
| sed -n "s/^$CONFIG\.@servers\[\([0-9]\+\)\]=servers$/\1/p"
|
||
}
|
||
|
||
start_one_idx() {
|
||
local idx="$1"
|
||
|
||
local enable_server port delay extra_options
|
||
enable_server="$(uci -q get $CONFIG.@servers[$idx].enable_server)"
|
||
port="$(uci -q get $CONFIG.@servers[$idx].port)"
|
||
delay="$(uci -q get $CONFIG.@servers[$idx].delay)"
|
||
extra_options="$(uci -q get $CONFIG.@servers[$idx].extra_options)"
|
||
|
||
# 默认值
|
||
[ -n "$enable_server" ] || enable_server="1"
|
||
[ -n "$port" ] || port="5201"
|
||
[ -n "$delay" ] || delay="0"
|
||
|
||
[ "$enable_server" = "1" ] || return 0
|
||
|
||
# 端口合法性兜底
|
||
case "$port" in
|
||
*[!0-9]*|'') $LOGGER "Skip invalid port in @servers[$idx]"; return 0 ;;
|
||
esac
|
||
[ "$port" -ge 1 ] 2>/dev/null && [ "$port" -le 65535 ] 2>/dev/null || {
|
||
$LOGGER "Skip invalid port [$port] in @servers[$idx]"
|
||
return 0
|
||
}
|
||
|
||
# delay 合法性兜底
|
||
case "$delay" in
|
||
*[!0-9]*|'') delay=0 ;;
|
||
esac
|
||
|
||
# extra_options 安全兜底
|
||
if [ -n "$extra_options" ] && ! is_safe_extra_opts "$extra_options"; then
|
||
$LOGGER "Rejected unsafe extra_options on port [$port] (@servers[$idx])"
|
||
extra_options=""
|
||
fi
|
||
|
||
$LOGGER "Starting @servers[$idx] port=[$port] delay=[$delay] ..."
|
||
|
||
# procd 实例名按端口
|
||
procd_open_instance "iperf3_${port}"
|
||
|
||
# 不用 -D;delay 用 sh -c 不阻塞
|
||
if [ "$delay" -gt 0 ] 2>/dev/null; then
|
||
if [ -n "$extra_options" ]; then
|
||
procd_set_param command /bin/sh -c "sleep $delay; exec $PROG -s -p $port $extra_options"
|
||
else
|
||
procd_set_param command /bin/sh -c "sleep $delay; exec $PROG -s -p $port"
|
||
fi
|
||
else
|
||
if [ -n "$extra_options" ]; then
|
||
procd_set_param command "$PROG" -s -p "$port" $extra_options
|
||
else
|
||
procd_set_param command "$PROG" -s -p "$port"
|
||
fi
|
||
fi
|
||
|
||
procd_set_param respawn 3600 5 5
|
||
procd_set_param stdout 1
|
||
procd_set_param stderr 1
|
||
procd_close_instance
|
||
}
|
||
|
||
start_service() {
|
||
[ -x "$PROG" ] || { $LOGGER "iperf3 not found: $PROG"; return 1; }
|
||
|
||
# 主开关:直接用 uci 读取匿名段
|
||
local main_enable
|
||
main_enable="$(uci -q get $CONFIG.@iperf3-server[0].main_enable)"
|
||
[ -n "$main_enable" ] || main_enable="0"
|
||
|
||
[ "$main_enable" = "1" ] || {
|
||
$LOGGER "iPerf3 Server is disabled ..."
|
||
return 0
|
||
}
|
||
|
||
# 遍历 servers 索引
|
||
local idx
|
||
for idx in $(get_server_indexes); do
|
||
start_one_idx "$idx"
|
||
done
|
||
|
||
return 0
|
||
}
|
||
|
||
stop_one_idx() {
|
||
local idx="$1"
|
||
local enable_server port
|
||
|
||
enable_server="$(uci -q get $CONFIG.@servers[$idx].enable_server)"
|
||
[ -n "$enable_server" ] || enable_server="1"
|
||
[ "$enable_server" = "1" ] || return 0
|
||
|
||
port="$(uci -q get $CONFIG.@servers[$idx].port)"
|
||
[ -n "$port" ] || port="5201"
|
||
|
||
case "$port" in
|
||
*[!0-9]*|'') return 0 ;;
|
||
esac
|
||
|
||
kill_by_port "$port"
|
||
}
|
||
|
||
stop_service() {
|
||
$LOGGER "Stopping iPerf3 Server ..."
|
||
|
||
# 按 servers 列表逐个端口清理(不误杀其它 iperf3)
|
||
local idx
|
||
for idx in $(get_server_indexes); do
|
||
stop_one_idx "$idx"
|
||
done
|
||
|
||
return 0
|
||
}
|
||
|
||
reload_service() {
|
||
# /etc/init.d/iperf3-server reload
|
||
stop
|
||
start
|
||
}
|
||
|
||
service_triggers() {
|
||
procd_add_reload_trigger "$CONFIG"
|
||
}
|