|
@@ -28,8 +28,9 @@ function index()
|
|
|
entry({"admin", "services", "shadowsocksr", "reset"}, call("act_reset"))
|
|
entry({"admin", "services", "shadowsocksr", "reset"}, call("act_reset"))
|
|
|
entry({"admin", "services", "shadowsocksr", "restart"}, call("act_restart"))
|
|
entry({"admin", "services", "shadowsocksr", "restart"}, call("act_restart"))
|
|
|
entry({"admin", "services", "shadowsocksr", "delete"}, call("act_delete"))
|
|
entry({"admin", "services", "shadowsocksr", "delete"}, call("act_delete"))
|
|
|
- --[[Backup]]
|
|
|
|
|
|
|
+ --[[Backup]]
|
|
|
entry({"admin", "services", "shadowsocksr", "backup"}, call("create_backup")).leaf = true
|
|
entry({"admin", "services", "shadowsocksr", "backup"}, call("create_backup")).leaf = true
|
|
|
|
|
+
|
|
|
end
|
|
end
|
|
|
|
|
|
|
|
function subscribe()
|
|
function subscribe()
|
|
@@ -46,40 +47,74 @@ function act_status()
|
|
|
end
|
|
end
|
|
|
|
|
|
|
|
function act_ping()
|
|
function act_ping()
|
|
|
- local e = {}
|
|
|
|
|
- local domain = luci.http.formvalue("domain")
|
|
|
|
|
- local port = luci.http.formvalue("port")
|
|
|
|
|
- local transport = luci.http.formvalue("transport")
|
|
|
|
|
- local wsPath = luci.http.formvalue("wsPath")
|
|
|
|
|
- local tls = luci.http.formvalue("tls")
|
|
|
|
|
- e.index = luci.http.formvalue("index")
|
|
|
|
|
- local iret = luci.sys.call("ipset add ss_spec_wan_ac " .. domain .. " 2>/dev/null")
|
|
|
|
|
- if transport == "ws" then
|
|
|
|
|
- local prefix = tls=='1' and "https://" or "http://"
|
|
|
|
|
- local address = prefix..domain..':'..port..wsPath
|
|
|
|
|
- local result = luci.sys.exec("curl --http1.1 -m 2 -ksN -o /dev/null -w 'time_connect=%{time_connect}\nhttp_code=%{http_code}' -H 'Connection: Upgrade' -H 'Upgrade: websocket' -H 'Sec-WebSocket-Key: SGVsbG8sIHdvcmxkIQ==' -H 'Sec-WebSocket-Version: 13' "..address)
|
|
|
|
|
- e.socket = string.match(result,"http_code=(%d+)")=="101"
|
|
|
|
|
- e.ping = tonumber(string.match(result, "time_connect=(%d+.%d%d%d)"))*1000
|
|
|
|
|
- else
|
|
|
|
|
- local socket = nixio.socket("inet", "stream")
|
|
|
|
|
- socket:setopt("socket", "rcvtimeo", 3)
|
|
|
|
|
- socket:setopt("socket", "sndtimeo", 3)
|
|
|
|
|
- e.socket = socket:connect(domain, port)
|
|
|
|
|
- socket:close()
|
|
|
|
|
- e.ping = luci.sys.exec(string.format("echo -n $(tcping -q -c 1 -i 1 -t 2 -p %s %s 2>&1 | grep -o 'time=[0-9]*' | awk -F '=' '{print $2}') 2>/dev/null", port, domain))
|
|
|
|
|
- if (e.ping == "") then
|
|
|
|
|
- e.ping = luci.sys.exec("echo -n $(ping -c 1 -W 1 %q 2>&1 | grep -o 'time=[0-9]*' | awk -F '=' '{print $2}') 2>/dev/null" % domain)
|
|
|
|
|
- if (e.ping == "") then
|
|
|
|
|
- -- UDP ping test using nping
|
|
|
|
|
- e.ping = luci.sys.exec(string.format("echo -n $(nping --udp -c 1 -p %s %s 2>/dev/null | grep -o 'Avg rtt: [0-9.]*ms' | awk '{print $3}' | sed 's/ms//' | head -1) 2>/dev/null", port, domain))
|
|
|
|
|
- end
|
|
|
|
|
- end
|
|
|
|
|
- end
|
|
|
|
|
- if (iret == 0) then
|
|
|
|
|
- luci.sys.call(" ipset del ss_spec_wan_ac " .. domain)
|
|
|
|
|
- end
|
|
|
|
|
- luci.http.prepare_content("application/json")
|
|
|
|
|
- luci.http.write_json(e)
|
|
|
|
|
|
|
+ local e = {}
|
|
|
|
|
+ local domain = luci.http.formvalue("domain")
|
|
|
|
|
+ local port = tonumber(luci.http.formvalue("port") or 0)
|
|
|
|
|
+ local transport = luci.http.formvalue("transport")
|
|
|
|
|
+ local wsPath = luci.http.formvalue("wsPath") or ""
|
|
|
|
|
+ local tls = luci.http.formvalue("tls")
|
|
|
|
|
+ e.index = luci.http.formvalue("index")
|
|
|
|
|
+
|
|
|
|
|
+ local use_nft = luci.sys.call("command -v nft >/dev/null") == 0
|
|
|
|
|
+ local iret = false
|
|
|
|
|
+
|
|
|
|
|
+ if use_nft then
|
|
|
|
|
+ iret = luci.sys.call("nft add element inet ss_spec ss_spec_wan_ac { " .. domain .. " } 2>/dev/null") == 0
|
|
|
|
|
+ else
|
|
|
|
|
+ iret = luci.sys.call("ipset add ss_spec_wan_ac " .. domain .. " 2>/dev/null") == 0
|
|
|
|
|
+ end
|
|
|
|
|
+
|
|
|
|
|
+ if transport == "ws" then
|
|
|
|
|
+ local prefix = tls == '1' and "https://" or "http://"
|
|
|
|
|
+ local address = prefix .. domain .. ':' .. port .. wsPath
|
|
|
|
|
+ local result = luci.sys.exec(
|
|
|
|
|
+ "curl --http1.1 -m 2 -ksN -o /dev/null " ..
|
|
|
|
|
+ "-w 'time_connect=%{time_connect}\nhttp_code=%{http_code}' " ..
|
|
|
|
|
+ "-H 'Connection: Upgrade' -H 'Upgrade: websocket' " ..
|
|
|
|
|
+ "-H 'Sec-WebSocket-Key: SGVsbG8sIHdvcmxkIQ==' " ..
|
|
|
|
|
+ "-H 'Sec-WebSocket-Version: 13' " .. address
|
|
|
|
|
+ )
|
|
|
|
|
+ e.socket = string.match(result,"http_code=(%d+)") == "101"
|
|
|
|
|
+ local ping_time = tonumber(string.match(result, "time_connect=(%d+.%d%d%d)"))
|
|
|
|
|
+ e.ping = ping_time and ping_time * 1000 or nil
|
|
|
|
|
+ else
|
|
|
|
|
+ -- TCP ping
|
|
|
|
|
+ local socket = nixio.socket("inet", "stream")
|
|
|
|
|
+ socket:setopt("socket", "rcvtimeo", 3)
|
|
|
|
|
+ socket:setopt("socket", "sndtimeo", 3)
|
|
|
|
|
+ e.socket = socket:connect(domain, port)
|
|
|
|
|
+ socket:close()
|
|
|
|
|
+
|
|
|
|
|
+ e.ping = tonumber(luci.sys.exec(string.format(
|
|
|
|
|
+ "tcping -q -c 1 -i 1 -t 2 -p %d %s 2>/dev/null | grep -o 'time=[0-9]*' | awk -F '=' '{print $2}'",
|
|
|
|
|
+ port, domain
|
|
|
|
|
+ )))
|
|
|
|
|
+
|
|
|
|
|
+ if not e.ping then
|
|
|
|
|
+ e.ping = tonumber(luci.sys.exec(string.format(
|
|
|
|
|
+ "ping -c 1 -W 1 %s 2>/dev/null | grep -o 'time=[0-9]*' | awk -F '=' '{print $2}'",
|
|
|
|
|
+ domain
|
|
|
|
|
+ )))
|
|
|
|
|
+ end
|
|
|
|
|
+
|
|
|
|
|
+ if not e.ping then
|
|
|
|
|
+ e.ping = tonumber(luci.sys.exec(string.format(
|
|
|
|
|
+ "nping --udp -c 1 -p %d %s 2>/dev/null | grep -o 'Avg rtt: [0-9.]*ms' | awk '{print $3}' | sed 's/ms//' | head -1",
|
|
|
|
|
+ port, domain
|
|
|
|
|
+ )))
|
|
|
|
|
+ end
|
|
|
|
|
+ end
|
|
|
|
|
+
|
|
|
|
|
+ if iret then
|
|
|
|
|
+ if use_nft then
|
|
|
|
|
+ luci.sys.call("nft delete element inet ss_spec ss_spec_wan_ac { " .. domain .. " } 2>/dev/null")
|
|
|
|
|
+ else
|
|
|
|
|
+ luci.sys.call("ipset del ss_spec_wan_ac " .. domain .. " 2>/dev/null")
|
|
|
|
|
+ end
|
|
|
|
|
+ end
|
|
|
|
|
+
|
|
|
|
|
+ luci.http.prepare_content("application/json")
|
|
|
|
|
+ luci.http.write_json(e)
|
|
|
end
|
|
end
|
|
|
|
|
|
|
|
function check_status()
|
|
function check_status()
|
|
@@ -101,28 +136,46 @@ function check_port()
|
|
|
local s
|
|
local s
|
|
|
local server_name = ""
|
|
local server_name = ""
|
|
|
local uci = require "luci.model.uci".cursor()
|
|
local uci = require "luci.model.uci".cursor()
|
|
|
- local iret = 1
|
|
|
|
|
|
|
+ local use_nft = luci.sys.call("command -v nft >/dev/null") == 0
|
|
|
|
|
+
|
|
|
uci:foreach("shadowsocksr", "servers", function(s)
|
|
uci:foreach("shadowsocksr", "servers", function(s)
|
|
|
if s.alias then
|
|
if s.alias then
|
|
|
server_name = s.alias
|
|
server_name = s.alias
|
|
|
elseif s.server and s.server_port then
|
|
elseif s.server and s.server_port then
|
|
|
- server_name = "%s:%s" % {s.server, s.server_port}
|
|
|
|
|
|
|
+ server_name = s.server .. ":" .. s.server_port
|
|
|
|
|
+ end
|
|
|
|
|
+
|
|
|
|
|
+ -- 临时加入 set
|
|
|
|
|
+ local iret = false
|
|
|
|
|
+ if use_nft then
|
|
|
|
|
+ iret = luci.sys.call("nft add element inet ss_spec ss_spec_wan_ac { " .. s.server .. " } 2>/dev/null") == 0
|
|
|
|
|
+ else
|
|
|
|
|
+ iret = luci.sys.call("ipset add ss_spec_wan_ac " .. s.server .. " 2>/dev/null") == 0
|
|
|
end
|
|
end
|
|
|
- iret = luci.sys.call("ipset add ss_spec_wan_ac " .. s.server .. " 2>/dev/null")
|
|
|
|
|
- socket = nixio.socket("inet", "stream")
|
|
|
|
|
|
|
+
|
|
|
|
|
+ -- TCP 测试
|
|
|
|
|
+ local socket = nixio.socket("inet", "stream")
|
|
|
socket:setopt("socket", "rcvtimeo", 3)
|
|
socket:setopt("socket", "rcvtimeo", 3)
|
|
|
socket:setopt("socket", "sndtimeo", 3)
|
|
socket:setopt("socket", "sndtimeo", 3)
|
|
|
- ret = socket:connect(s.server, s.server_port)
|
|
|
|
|
- if tostring(ret) == "true" then
|
|
|
|
|
- socket:close()
|
|
|
|
|
- retstring = retstring .. "<font><b style='color:green'>[" .. server_name .. "] OK.</b></font><br />"
|
|
|
|
|
|
|
+ local ret = socket:connect(s.server, s.server_port)
|
|
|
|
|
+ socket:close()
|
|
|
|
|
+
|
|
|
|
|
+ if ret then
|
|
|
|
|
+ retstring = retstring .. string.format("<font><b style='color:green'>[%s] OK.</b></font><br />", server_name)
|
|
|
else
|
|
else
|
|
|
- retstring = retstring .. "<font><b style='color:red'>[" .. server_name .. "] Error.</b></font><br />"
|
|
|
|
|
|
|
+ retstring = retstring .. string.format("<font><b style='color:red'>[%s] Error.</b></font><br />", server_name)
|
|
|
end
|
|
end
|
|
|
- if iret == 0 then
|
|
|
|
|
- luci.sys.call("ipset del ss_spec_wan_ac " .. s.server)
|
|
|
|
|
|
|
+
|
|
|
|
|
+ -- 删除临时 set
|
|
|
|
|
+ if iret then
|
|
|
|
|
+ if use_nft then
|
|
|
|
|
+ luci.sys.call("nft delete element inet ss_spec ss_spec_wan_ac { " .. s.server .. " } 2>/dev/null")
|
|
|
|
|
+ else
|
|
|
|
|
+ luci.sys.call("ipset del ss_spec_wan_ac " .. s.server)
|
|
|
|
|
+ end
|
|
|
end
|
|
end
|
|
|
end)
|
|
end)
|
|
|
|
|
+
|
|
|
luci.http.prepare_content("application/json")
|
|
luci.http.prepare_content("application/json")
|
|
|
luci.http.write_json({ret = retstring})
|
|
luci.http.write_json({ret = retstring})
|
|
|
end
|
|
end
|