op-packages/luci-app-iperf3-server/root/etc/init.d/iperf3-server
github-actions[bot] 32600acc60 🌴 Sync 2026-03-05 23:51:42
2026-03-05 23:51:42 +08:00

185 lines
4.5 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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}"
# 不用 -Ddelay 用 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"
}