mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-10-30 03:35:13 +08:00
🌴 Sync 2026-03-05 23:51:42
This commit is contained in:
1 parent
97c049ed0a
commit
0acff03804
14253 files changed
+3893239
No files matched your search
+185
@@ -0,0 +1,185 @@
|
||||
module("luci.controller.iperf3-server", package.seeall)
|
||||
|
||||
function index()
|
||||
local fs = require "nixio.fs"
|
||||
|
||||
if not fs.access("/etc/config/iperf3-server") then
|
||||
return
|
||||
end
|
||||
|
||||
local page
|
||||
|
||||
page = entry({"admin", "services", "iperf3-server"}, cbi("iperf3-server"), _("iPerf3 Server"), 99)
|
||||
page.acl_depends = { "luci-app-iperf3-server" }
|
||||
|
||||
page = entry({"admin", "services", "iperf3-server", "status"}, call("act_status"))
|
||||
page.leaf = true
|
||||
page.acl_depends = { "luci-app-iperf3-server" }
|
||||
|
||||
page = entry({"admin", "services", "iperf3-server", "start"}, call("act_start"))
|
||||
page.leaf = true
|
||||
page.acl_depends = { "luci-app-iperf3-server" }
|
||||
|
||||
page = entry({"admin", "services", "iperf3-server", "stop"}, call("act_stop"))
|
||||
page.leaf = true
|
||||
page.acl_depends = { "luci-app-iperf3-server" }
|
||||
|
||||
page = entry({"admin", "services", "iperf3-server", "restart"}, call("act_restart"))
|
||||
page.leaf = true
|
||||
page.acl_depends = { "luci-app-iperf3-server" }
|
||||
end
|
||||
|
||||
|
||||
local function json_ok(extra)
|
||||
local e = extra or {}
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
|
||||
function act_status()
|
||||
local uci = require("luci.model.uci").cursor()
|
||||
local sys = require("luci.sys")
|
||||
|
||||
local result = {
|
||||
running = false, -- 是否任意一个 server 正常运行
|
||||
servers = {} -- 每个端口的详细状态
|
||||
}
|
||||
|
||||
-- 解析 /proc/net/tcp & /proc/net/tcp6,判断端口是否 LISTEN
|
||||
local function is_listening_in_proc(path, port)
|
||||
local f = io.open(path, "r")
|
||||
if not f then return false end
|
||||
|
||||
local hex = string.format("%04X", port) -- 端口 16 进制,大写,固定 4 位
|
||||
-- /proc/net/tcp 列格式: sl local_address rem_address st ...
|
||||
-- local_address: AAAAAAAA:PPPP
|
||||
-- st = 0A 表示 LISTEN
|
||||
for line in f:lines() do
|
||||
-- 跳过表头
|
||||
if not line:match("^%s*sl%s+") then
|
||||
local st = line:match("^%s*%d+:%s+%x+:" .. hex .. "%s+%x+:%x+%s+(%x+)")
|
||||
if st == "0A" then
|
||||
f:close()
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
f:close()
|
||||
return false
|
||||
end
|
||||
|
||||
local function is_listening(port)
|
||||
-- IPv4 LISTEN
|
||||
if is_listening_in_proc("/proc/net/tcp", port) then
|
||||
return true
|
||||
end
|
||||
-- IPv6 LISTEN(有的系统会只在 tcp6 里出现)
|
||||
if is_listening_in_proc("/proc/net/tcp6", port) then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- 用 ps 判断:是否存在 iperf3 server / delay 阶段 sleep+iperf3
|
||||
local ps = sys.exec("ps w 2>/dev/null") or ""
|
||||
|
||||
local function has_iperf3_server_proc(port)
|
||||
local p = tostring(port)
|
||||
|
||||
for line in ps:gmatch("[^\r\n]+") do
|
||||
-- 只要这行同时包含:
|
||||
-- 1) iperf3
|
||||
-- 2) -s(server)
|
||||
-- 3) -p 端口(支持 "-p 5201" 或 "-p5201")
|
||||
if line:find("iperf3", 1, true) then
|
||||
local hasS = line:match("%-s") ~= nil
|
||||
local hasP = (line:match("%-p%s*" .. p .. "%f[^%d]") ~= nil) or (line:match("%-p" .. p .. "%f[^%d]") ~= nil)
|
||||
if hasS and hasP then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
local function has_delay_pending_proc(port)
|
||||
local p = tostring(port)
|
||||
for line in ps:gmatch("[^\r\n]+") do
|
||||
-- 匹配 sh -c "sleep N; exec iperf3 -s -p <port> ..."
|
||||
if (line:find("/bin/sh", 1, true) or line:find("sh -c", 1, true))
|
||||
and line:find("sleep", 1, true)
|
||||
and line:find("iperf3", 1, true)
|
||||
and (line:match("%-p%s*" .. p .. "%f[^%d]") or line:match("%-p" .. p .. "%f[^%d]"))
|
||||
then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
uci:foreach("iperf3-server", "servers", function(s)
|
||||
local port = tonumber(s.port)
|
||||
local enabled = (s.enable_server == "1")
|
||||
|
||||
if not port then
|
||||
return
|
||||
end
|
||||
|
||||
local listen = is_listening(port)
|
||||
local iperf3_proc = has_iperf3_server_proc(port)
|
||||
local delay_pending = has_delay_pending_proc(port)
|
||||
|
||||
local state, detail
|
||||
if not enabled then
|
||||
state = "disabled"
|
||||
detail = "detail_disabled"
|
||||
else
|
||||
if delay_pending and not listen then
|
||||
state = "delay"
|
||||
detail = "detail_delay"
|
||||
elseif listen and iperf3_proc then
|
||||
state = "running"
|
||||
detail = "detail_running"
|
||||
result.running = true
|
||||
elseif listen and not iperf3_proc then
|
||||
state = "conflict"
|
||||
detail = "detail_conflict"
|
||||
else
|
||||
state = "stopped"
|
||||
detail = "detail_stopped"
|
||||
end
|
||||
end
|
||||
|
||||
result.servers[#result.servers + 1] = {
|
||||
port = port,
|
||||
enable = enabled,
|
||||
listen = listen,
|
||||
state = state,
|
||||
detail = detail
|
||||
}
|
||||
end)
|
||||
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(result)
|
||||
end
|
||||
|
||||
|
||||
|
||||
function act_start()
|
||||
local rc = luci.sys.call("/etc/init.d/iperf3-server start >/dev/null 2>&1")
|
||||
json_ok({ ok = (rc == 0) })
|
||||
end
|
||||
|
||||
function act_stop()
|
||||
local rc = luci.sys.call("/etc/init.d/iperf3-server stop >/dev/null 2>&1")
|
||||
json_ok({ ok = (rc == 0) })
|
||||
end
|
||||
|
||||
function act_restart()
|
||||
local rc = luci.sys.call("/etc/init.d/iperf3-server restart >/dev/null 2>&1")
|
||||
json_ok({ ok = (rc == 0) })
|
||||
end
|
||||
Reference in new issue
Block a user