update 2023-04-07 16:21:24
This commit is contained in:
parent
30f387f142
commit
573e989a66
|
@ -126,7 +126,7 @@ update_rules() {
|
||||||
yhosts_rules_local=`cat /usr/share/koolproxy/data/rules/yhosts.txt | sed -n '1p' | cut -d ":" -f2`
|
yhosts_rules_local=`cat /usr/share/koolproxy/data/rules/yhosts.txt | sed -n '1p' | cut -d ":" -f2`
|
||||||
antiad_rules_local=`cat /usr/share/koolproxy/data/rules/antiad.txt | sed -n '2p' | cut -d "=" -f2`
|
antiad_rules_local=`cat /usr/share/koolproxy/data/rules/antiad.txt | sed -n '2p' | cut -d "=" -f2`
|
||||||
koolproxy_rules_local=`cat /usr/share/koolproxy/data/rules/koolproxy.txt | sed -n '3p'|awk '{print $3,$4}'`
|
koolproxy_rules_local=`cat /usr/share/koolproxy/data/rules/koolproxy.txt | sed -n '3p'|awk '{print $3,$4}'`
|
||||||
adgk_rules_local=`cat /usr/share/koolproxy/data/rules/adgk.txt | sed -n '1p'|awk '{print $3}'`
|
adgk_rules_local=`cat /usr/share/koolproxy/data/rules/adgk.txt | sed -n '2p'|awk '{print $3}'`
|
||||||
echo $(date "+%F %T"): -------------------AdGuard规则 Version $adg_rules_local >>$LOGFILE
|
echo $(date "+%F %T"): -------------------AdGuard规则 Version $adg_rules_local >>$LOGFILE
|
||||||
echo $(date "+%F %T"): -------------------Steven规则 Version $steven_rules_local >>$LOGFILE
|
echo $(date "+%F %T"): -------------------Steven规则 Version $steven_rules_local >>$LOGFILE
|
||||||
echo $(date "+%F %T"): -------------------Yhosts规则 Version $yhosts_rules_local >>$LOGFILE
|
echo $(date "+%F %T"): -------------------Yhosts规则 Version $yhosts_rules_local >>$LOGFILE
|
||||||
|
|
|
@ -126,7 +126,7 @@ update_rules() {
|
||||||
yhosts_rules_local=`cat /usr/share/koolproxy/data/rules/yhosts.txt | sed -n '1p' | cut -d ":" -f2`
|
yhosts_rules_local=`cat /usr/share/koolproxy/data/rules/yhosts.txt | sed -n '1p' | cut -d ":" -f2`
|
||||||
antiad_rules_local=`cat /usr/share/koolproxy/data/rules/antiad.txt | sed -n '2p' | cut -d "=" -f2`
|
antiad_rules_local=`cat /usr/share/koolproxy/data/rules/antiad.txt | sed -n '2p' | cut -d "=" -f2`
|
||||||
koolproxy_rules_local=`cat /usr/share/koolproxy/data/rules/koolproxy.txt | sed -n '3p'|awk '{print $3,$4}'`
|
koolproxy_rules_local=`cat /usr/share/koolproxy/data/rules/koolproxy.txt | sed -n '3p'|awk '{print $3,$4}'`
|
||||||
adgk_rules_local=`cat /usr/share/koolproxy/data/rules/adgk.txt | sed -n '1p'|awk '{print $3}'`
|
adgk_rules_local=`cat /usr/share/koolproxy/data/rules/adgk.txt | sed -n '2p'|awk '{print $3}'`
|
||||||
echo $(date "+%F %T"): -------------------AdGuard规则 Version $adg_rules_local >>$LOGFILE
|
echo $(date "+%F %T"): -------------------AdGuard规则 Version $adg_rules_local >>$LOGFILE
|
||||||
echo $(date "+%F %T"): -------------------Steven规则 Version $steven_rules_local >>$LOGFILE
|
echo $(date "+%F %T"): -------------------Steven规则 Version $steven_rules_local >>$LOGFILE
|
||||||
echo $(date "+%F %T"): -------------------Yhosts规则 Version $yhosts_rules_local >>$LOGFILE
|
echo $(date "+%F %T"): -------------------Yhosts规则 Version $yhosts_rules_local >>$LOGFILE
|
||||||
|
|
|
@ -5,11 +5,12 @@
|
||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=luci-app-passwall2
|
PKG_NAME:=luci-app-passwall2
|
||||||
PKG_VERSION:=1.10
|
PKG_VERSION:=1.11
|
||||||
PKG_RELEASE:=6
|
PKG_RELEASE:=1
|
||||||
|
|
||||||
PKG_CONFIG_DEPENDS:= \
|
PKG_CONFIG_DEPENDS:= \
|
||||||
CONFIG_PACKAGE_$(PKG_NAME)_Transparent_Proxy \
|
CONFIG_PACKAGE_$(PKG_NAME)_Transparent_Proxy \
|
||||||
|
CONFIG_PACKAGE_$(PKG_NAME)_Transparent_Proxy_Iptables-nft \
|
||||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Brook \
|
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Brook \
|
||||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria \
|
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria \
|
||||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_IPv6_Nat \
|
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_IPv6_Nat \
|
||||||
|
@ -52,6 +53,7 @@ menu "Configuration"
|
||||||
config PACKAGE_$(PKG_NAME)_Transparent_Proxy
|
config PACKAGE_$(PKG_NAME)_Transparent_Proxy
|
||||||
bool "Transparent Proxy"
|
bool "Transparent Proxy"
|
||||||
select PACKAGE_dnsmasq-full
|
select PACKAGE_dnsmasq-full
|
||||||
|
select PACKAGE_dnsmasq_full_ipset
|
||||||
select PACKAGE_ipset
|
select PACKAGE_ipset
|
||||||
select PACKAGE_iptables
|
select PACKAGE_iptables
|
||||||
select PACKAGE_iptables-zz-legacy
|
select PACKAGE_iptables-zz-legacy
|
||||||
|
@ -61,7 +63,21 @@ config PACKAGE_$(PKG_NAME)_Transparent_Proxy
|
||||||
select PACKAGE_iptables-mod-conntrack-extra
|
select PACKAGE_iptables-mod-conntrack-extra
|
||||||
select PACKAGE_kmod-ipt-nat
|
select PACKAGE_kmod-ipt-nat
|
||||||
depends on PACKAGE_$(PKG_NAME)
|
depends on PACKAGE_$(PKG_NAME)
|
||||||
default y
|
default y if ! PACKAGE_firewall4
|
||||||
|
|
||||||
|
config PACKAGE_$(PKG_NAME)_Transparent_Proxy_Iptables-nft
|
||||||
|
bool "Transparent Proxy Use Iptables-nft"
|
||||||
|
select PACKAGE_dnsmasq-full
|
||||||
|
select PACKAGE_dnsmasq_full_ipset
|
||||||
|
select PACKAGE_ipset
|
||||||
|
select PACKAGE_iptables-nft
|
||||||
|
select PACKAGE_iptables-mod-iprange
|
||||||
|
select PACKAGE_iptables-mod-socket
|
||||||
|
select PACKAGE_iptables-mod-tproxy
|
||||||
|
select PACKAGE_iptables-mod-conntrack-extra
|
||||||
|
select PACKAGE_kmod-ipt-nat
|
||||||
|
depends on PACKAGE_$(PKG_NAME)
|
||||||
|
default y if PACKAGE_firewall4
|
||||||
|
|
||||||
config PACKAGE_$(PKG_NAME)_INCLUDE_Brook
|
config PACKAGE_$(PKG_NAME)_INCLUDE_Brook
|
||||||
bool "Include Brook"
|
bool "Include Brook"
|
||||||
|
|
|
@ -129,10 +129,21 @@ for k, e in ipairs(api.get_valid_nodes()) do
|
||||||
end
|
end
|
||||||
|
|
||||||
-- 负载均衡列表
|
-- 负载均衡列表
|
||||||
balancing_node = s:option(DynamicList, "balancing_node", translate("Load balancing node list"), translate("Load balancing node list, <a target='_blank' href='https://toutyrater.github.io/routing/balance2.html'>document</a>"))
|
local balancing_node = s:option(DynamicList, "balancing_node", translate("Load balancing node list"), translate("Load balancing node list, <a target='_blank' href='https://toutyrater.github.io/routing/balance2.html'>document</a>"))
|
||||||
for k, v in pairs(nodes_table) do balancing_node:value(v.id, v.remarks) end
|
for k, v in pairs(nodes_table) do balancing_node:value(v.id, v.remarks) end
|
||||||
balancing_node:depends("protocol", "_balancing")
|
balancing_node:depends("protocol", "_balancing")
|
||||||
|
|
||||||
|
local balancingStrategy = s:option(ListValue, "balancingStrategy", translate("Balancing Strategy"))
|
||||||
|
balancingStrategy:depends("protocol", "_balancing")
|
||||||
|
balancingStrategy:value("random")
|
||||||
|
balancingStrategy:value("leastPing")
|
||||||
|
balancingStrategy.default = "random"
|
||||||
|
|
||||||
|
local probeInterval = s:option(Value, "probeInterval", translate("Probe Interval"))
|
||||||
|
probeInterval:depends("balancingStrategy", "leastPing")
|
||||||
|
probeInterval.default = "1m"
|
||||||
|
probeInterval.description = translate("The interval between initiating probes. Every time this time elapses, a server status check is performed on a server. The time format is numbers + units, such as '10s', '2h45m', and the supported time units are <code>ns</code>, <code>us</code>, <code>ms</code>, <code>s</code>, <code>m</code>, <code>h</code>, which correspond to nanoseconds, microseconds, milliseconds, seconds, minutes, and hours, respectively.")
|
||||||
|
|
||||||
-- 分流
|
-- 分流
|
||||||
uci:foreach(appname, "shunt_rules", function(e)
|
uci:foreach(appname, "shunt_rules", function(e)
|
||||||
if e[".name"] and e.remarks then
|
if e[".name"] and e.remarks then
|
||||||
|
@ -192,13 +203,11 @@ domainStrategy.description = "<br /><ul><li>" .. translate("'AsIs': Only use dom
|
||||||
.. "</li><li>" .. translate("'IPIfNonMatch': When no rule matches current domain, resolves it into IP addresses (A or AAAA records) and try all rules again.")
|
.. "</li><li>" .. translate("'IPIfNonMatch': When no rule matches current domain, resolves it into IP addresses (A or AAAA records) and try all rules again.")
|
||||||
.. "</li><li>" .. translate("'IPOnDemand': As long as there is a IP-based rule, resolves the domain into IP immediately.")
|
.. "</li><li>" .. translate("'IPOnDemand': As long as there is a IP-based rule, resolves the domain into IP immediately.")
|
||||||
.. "</li></ul>"
|
.. "</li></ul>"
|
||||||
domainStrategy:depends("protocol", "_balancing")
|
|
||||||
domainStrategy:depends("protocol", "_shunt")
|
domainStrategy:depends("protocol", "_shunt")
|
||||||
|
|
||||||
domainMatcher = s:option(ListValue, "domainMatcher", translate("Domain matcher"))
|
domainMatcher = s:option(ListValue, "domainMatcher", translate("Domain matcher"))
|
||||||
domainMatcher:value("hybrid")
|
domainMatcher:value("hybrid")
|
||||||
domainMatcher:value("linear")
|
domainMatcher:value("linear")
|
||||||
domainMatcher:depends("protocol", "_balancing")
|
|
||||||
domainMatcher:depends("protocol", "_shunt")
|
domainMatcher:depends("protocol", "_shunt")
|
||||||
|
|
||||||
|
|
||||||
|
@ -544,9 +553,9 @@ xray_fingerprint:value("chrome")
|
||||||
xray_fingerprint:value("firefox")
|
xray_fingerprint:value("firefox")
|
||||||
xray_fingerprint:value("safari")
|
xray_fingerprint:value("safari")
|
||||||
xray_fingerprint:value("ios")
|
xray_fingerprint:value("ios")
|
||||||
xray_fingerprint:value("android")
|
--xray_fingerprint:value("android")
|
||||||
xray_fingerprint:value("edge")
|
xray_fingerprint:value("edge")
|
||||||
xray_fingerprint:value("360")
|
--xray_fingerprint:value("360")
|
||||||
xray_fingerprint:value("qq")
|
xray_fingerprint:value("qq")
|
||||||
xray_fingerprint:value("random")
|
xray_fingerprint:value("random")
|
||||||
xray_fingerprint:value("randomized")
|
xray_fingerprint:value("randomized")
|
||||||
|
@ -579,9 +588,9 @@ reality_fingerprint:value("chrome")
|
||||||
reality_fingerprint:value("firefox")
|
reality_fingerprint:value("firefox")
|
||||||
reality_fingerprint:value("safari")
|
reality_fingerprint:value("safari")
|
||||||
reality_fingerprint:value("ios")
|
reality_fingerprint:value("ios")
|
||||||
reality_fingerprint:value("android")
|
--reality_fingerprint:value("android")
|
||||||
reality_fingerprint:value("edge")
|
reality_fingerprint:value("edge")
|
||||||
reality_fingerprint:value("360")
|
--reality_fingerprint:value("360")
|
||||||
reality_fingerprint:value("qq")
|
reality_fingerprint:value("qq")
|
||||||
reality_fingerprint:value("random")
|
reality_fingerprint:value("random")
|
||||||
reality_fingerprint:value("randomized")
|
reality_fingerprint:value("randomized")
|
||||||
|
@ -638,6 +647,11 @@ wireguard_mtu = s:option(Value, "wireguard_mtu", translate("MTU"))
|
||||||
wireguard_mtu.default = "1420"
|
wireguard_mtu.default = "1420"
|
||||||
wireguard_mtu:depends({ type = "Xray", protocol = "wireguard" })
|
wireguard_mtu:depends({ type = "Xray", protocol = "wireguard" })
|
||||||
|
|
||||||
|
if api.compare_versions(api.get_app_version("xray"), ">=", "1.8.0") then
|
||||||
|
wireguard_reserved = s:option(Value, "wireguard_reserved", translate("Reserved"))
|
||||||
|
wireguard_reserved:depends({ type = "Xray", protocol = "wireguard" })
|
||||||
|
end
|
||||||
|
|
||||||
wireguard_keepAlive = s:option(Value, "wireguard_keepAlive", translate("Keep Alive"))
|
wireguard_keepAlive = s:option(Value, "wireguard_keepAlive", translate("Keep Alive"))
|
||||||
wireguard_keepAlive.default = "0"
|
wireguard_keepAlive.default = "0"
|
||||||
wireguard_keepAlive:depends({ type = "Xray", protocol = "wireguard" })
|
wireguard_keepAlive:depends({ type = "Xray", protocol = "wireguard" })
|
||||||
|
@ -833,6 +847,9 @@ hysteria_hop_interval:depends("type", "Hysteria")
|
||||||
hysteria_disable_mtu_discovery = s:option(Flag, "hysteria_disable_mtu_discovery", translate("Disable MTU detection"))
|
hysteria_disable_mtu_discovery = s:option(Flag, "hysteria_disable_mtu_discovery", translate("Disable MTU detection"))
|
||||||
hysteria_disable_mtu_discovery:depends("type", "Hysteria")
|
hysteria_disable_mtu_discovery:depends("type", "Hysteria")
|
||||||
|
|
||||||
|
hysteria_lazy_start = s:option(Flag, "hysteria_lazy_start", translate("Lazy Start"))
|
||||||
|
hysteria_lazy_start:depends("type", "Hysteria")
|
||||||
|
|
||||||
protocol.validate = function(self, value)
|
protocol.validate = function(self, value)
|
||||||
if value == "_shunt" or value == "_balancing" then
|
if value == "_shunt" or value == "_balancing" then
|
||||||
address.rmempty = true
|
address.rmempty = true
|
||||||
|
|
|
@ -13,6 +13,17 @@ command_timeout = 300
|
||||||
LEDE_BOARD = nil
|
LEDE_BOARD = nil
|
||||||
DISTRIB_TARGET = nil
|
DISTRIB_TARGET = nil
|
||||||
|
|
||||||
|
LOG_FILE = "/tmp/log/passwall2.log"
|
||||||
|
|
||||||
|
function log(...)
|
||||||
|
local result = os.date("%Y-%m-%d %H:%M:%S: ") .. table.concat({...}, " ")
|
||||||
|
local f, err = io.open(LOG_FILE, "a")
|
||||||
|
if f and err == nil then
|
||||||
|
f:write(result .. "\n")
|
||||||
|
f:close()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function exec_call(cmd)
|
function exec_call(cmd)
|
||||||
local process = io.popen(cmd .. '; echo -e "\n$?"')
|
local process = io.popen(cmd .. '; echo -e "\n$?"')
|
||||||
local lines = {}
|
local lines = {}
|
||||||
|
@ -355,7 +366,7 @@ function get_customed_path(e)
|
||||||
end
|
end
|
||||||
|
|
||||||
function is_finded(e)
|
function is_finded(e)
|
||||||
return luci.sys.exec('type -t -p "/bin/%s" -p "%s" "%s"' % {e, get_customed_path(e), e}) ~= "" and true or false
|
return luci.sys.exec('type -t -p "/bin/%s" -p "/usr/bin/%s" -p "%s" "%s"' % {e, e, get_customed_path(e), e}) ~= "" and true or false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,7 @@ function gen_config(var)
|
||||||
hop_interval = (node.hysteria_hop_interval) and tonumber(node.hysteria_hop_interval) or nil,
|
hop_interval = (node.hysteria_hop_interval) and tonumber(node.hysteria_hop_interval) or nil,
|
||||||
disable_mtu_discovery = (node.hysteria_disable_mtu_discovery) and true or false,
|
disable_mtu_discovery = (node.hysteria_disable_mtu_discovery) and true or false,
|
||||||
fast_open = (node.fast_open == "1") and true or false,
|
fast_open = (node.fast_open == "1") and true or false,
|
||||||
|
lazy_start = (node.hysteria_lazy_start) and true or false,
|
||||||
socks5 = (local_socks_address and local_socks_port) and {
|
socks5 = (local_socks_address and local_socks_port) and {
|
||||||
listen = local_socks_address .. ":" .. local_socks_port,
|
listen = local_socks_address .. ":" .. local_socks_port,
|
||||||
timeout = 300,
|
timeout = 300,
|
||||||
|
|
|
@ -106,6 +106,14 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if node.protocol == "wireguard" and node.wireguard_reserved then
|
||||||
|
local bytes = {}
|
||||||
|
node.wireguard_reserved:gsub("[^,]+", function(b)
|
||||||
|
bytes[#bytes+1] = tonumber(b)
|
||||||
|
end)
|
||||||
|
node.wireguard_reserved = #bytes > 0 and bytes or nil
|
||||||
|
end
|
||||||
|
|
||||||
result = {
|
result = {
|
||||||
_flag_tag = node_id,
|
_flag_tag = node_id,
|
||||||
_flag_proxy = proxy,
|
_flag_proxy = proxy,
|
||||||
|
@ -230,7 +238,8 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||||
keepAlive = node.wireguard_keepAlive and tonumber(node.wireguard_keepAlive) or nil
|
keepAlive = node.wireguard_keepAlive and tonumber(node.wireguard_keepAlive) or nil
|
||||||
}
|
}
|
||||||
} or nil,
|
} or nil,
|
||||||
mtu = (node.protocol == "wireguard" and node.wireguard_mtu) and tonumber(node.wireguard_mtu) or nil
|
mtu = (node.protocol == "wireguard" and node.wireguard_mtu) and tonumber(node.wireguard_mtu) or nil,
|
||||||
|
reserved = (node.protocol == "wireguard" and node.wireguard_reserved) and node.wireguard_reserved or nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
local alpn = {}
|
local alpn = {}
|
||||||
|
@ -522,6 +531,7 @@ function gen_config(var)
|
||||||
local inbounds = {}
|
local inbounds = {}
|
||||||
local outbounds = {}
|
local outbounds = {}
|
||||||
local routing = nil
|
local routing = nil
|
||||||
|
local observatory = nil
|
||||||
|
|
||||||
if local_socks_port then
|
if local_socks_port then
|
||||||
local inbound = {
|
local inbound = {
|
||||||
|
@ -817,10 +827,18 @@ function gen_config(var)
|
||||||
local outbound = gen_outbound(flag, node)
|
local outbound = gen_outbound(flag, node)
|
||||||
if outbound then table.insert(outbounds, outbound) end
|
if outbound then table.insert(outbounds, outbound) end
|
||||||
end
|
end
|
||||||
|
if node.balancingStrategy == "leastPing" then
|
||||||
|
observatory = {
|
||||||
|
subjectSelector = nodes,
|
||||||
|
probeInterval = node.probeInterval or "1m"
|
||||||
|
}
|
||||||
|
end
|
||||||
routing = {
|
routing = {
|
||||||
domainStrategy = node.domainStrategy or "AsIs",
|
balancers = {{
|
||||||
domainMatcher = node.domainMatcher or "hybrid",
|
tag = "balancer",
|
||||||
balancers = {{tag = "balancer", selector = nodes}},
|
selector = nodes,
|
||||||
|
strategy = {type = node.balancingStrategy or "random"}
|
||||||
|
}},
|
||||||
rules = {
|
rules = {
|
||||||
{type = "field", network = "tcp,udp", balancerTag = "balancer"}
|
{type = "field", network = "tcp,udp", balancerTag = "balancer"}
|
||||||
}
|
}
|
||||||
|
@ -1093,6 +1111,8 @@ function gen_config(var)
|
||||||
inbounds = inbounds,
|
inbounds = inbounds,
|
||||||
-- 传出连接
|
-- 传出连接
|
||||||
outbounds = outbounds,
|
outbounds = outbounds,
|
||||||
|
-- 连接观测
|
||||||
|
observatory = observatory,
|
||||||
-- 路由
|
-- 路由
|
||||||
routing = routing,
|
routing = routing,
|
||||||
-- 本地策略
|
-- 本地策略
|
||||||
|
@ -1277,7 +1297,7 @@ function gen_dns_config(var)
|
||||||
dns = {
|
dns = {
|
||||||
tag = "dns-in1",
|
tag = "dns-in1",
|
||||||
hosts = {},
|
hosts = {},
|
||||||
disableCache = (dns_cache and dns_cache == "0") and true or false,
|
disableCache = (dns_cache == "1") and false or true,
|
||||||
disableFallback = true,
|
disableFallback = true,
|
||||||
disableFallbackIfMatch = true,
|
disableFallbackIfMatch = true,
|
||||||
servers = {},
|
servers = {},
|
||||||
|
|
|
@ -56,26 +56,18 @@ local has_xray = api.is_finded("xray")
|
||||||
return b64decsafe(v);
|
return b64decsafe(v);
|
||||||
}
|
}
|
||||||
function parseNodeUrl(url) {
|
function parseNodeUrl(url) {
|
||||||
var m = url.match(/^(([^:\/?#]+:)?(?:\/\/((?:([^\/?#:]*)([^\/?#:]*)@)?([^\/?#:]*)(?::([^\/?#:]*))?)))?([^?#]*)(\?[^#]*)?(#.*)?$/),
|
let protocol = url.substring(0, url.indexOf("://")) + ":"
|
||||||
r = {
|
let str = "http" + url.substring(url.indexOf("://"))
|
||||||
hash: m[10] || "", // #asd
|
const parsedUrl = new URL(str);
|
||||||
host: m[3] || "", // localhost:257
|
var r = {
|
||||||
hostname: m[6] || "", // localhost
|
hash: parsedUrl.hash, // #asd
|
||||||
href: m[0] || "", // http://username:password@localhost:257/deploy/?asd=asd#asd
|
host: parsedUrl.host, // localhost:257
|
||||||
origin: m[1] || "", // http://username:password@localhost:257
|
hostname: parsedUrl.hostname, // localhost
|
||||||
pathname: m[8] || (m[1] ? "/" : ""), // /deploy/
|
port: parsedUrl.port, // 257
|
||||||
port: m[7] || "", // 257
|
search: parsedUrl.search, // ?asd=asd
|
||||||
protocol: m[2] || "", // http:
|
passwd: parsedUrl.username || parsedUrl.password // username
|
||||||
search: m[9] || "", // ?asd=asd
|
};
|
||||||
passwd: m[4] || "", // username
|
return r;
|
||||||
removed: m[5] || "" // password
|
|
||||||
};
|
|
||||||
if (r.protocol.length === 2) {
|
|
||||||
r.protocol = "file:///" + r.protocol.toUpperCase();
|
|
||||||
r.origin = r.protocol + "//" + r.host;
|
|
||||||
}
|
|
||||||
r.href = r.origin + r.pathname + r.search + r.hash;
|
|
||||||
return m && r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildUrl(btn, urlname, sid) {
|
function buildUrl(btn, urlname, sid) {
|
||||||
|
@ -130,15 +122,25 @@ local has_xray = api.is_finded("xray")
|
||||||
opt.client = urlname.indexOf("server") === -1;
|
opt.client = urlname.indexOf("server") === -1;
|
||||||
var v_type = opt.get("type").value;
|
var v_type = opt.get("type").value;
|
||||||
var v_alias = opt.get("remarks");
|
var v_alias = opt.get("remarks");
|
||||||
|
var _address = ""
|
||||||
|
try {
|
||||||
|
var v_server = opt.get("address");
|
||||||
|
const ipv6Regex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/;
|
||||||
|
if (ipv6Regex.test(v_server.value)) {
|
||||||
|
_address = "[" + v_server.value + "]"
|
||||||
|
} else {
|
||||||
|
_address = v_server.value
|
||||||
|
}
|
||||||
|
} catch(e) {
|
||||||
|
}
|
||||||
var url = null;
|
var url = null;
|
||||||
if (v_type === "SS") {
|
if (v_type === "SS") {
|
||||||
var v_server = opt.get("address");
|
|
||||||
var v_port = opt.get("port");
|
var v_port = opt.get("port");
|
||||||
var v_method = opt.get("ss_encrypt_method");
|
var v_method = opt.get("ss_encrypt_method");
|
||||||
var v_password = opt.get("password");
|
var v_password = opt.get("password");
|
||||||
|
|
||||||
url = b64encsafe(v_method.value + ":" + v_password.value) + "@" +
|
url = b64encsafe(v_method.value + ":" + v_password.value) + "@" +
|
||||||
v_server.value + ":" +
|
_address + ":" +
|
||||||
v_port.value + "/?";
|
v_port.value + "/?";
|
||||||
|
|
||||||
var params = "";
|
var params = "";
|
||||||
|
@ -160,7 +162,6 @@ local has_xray = api.is_finded("xray")
|
||||||
}
|
}
|
||||||
url += params;
|
url += params;
|
||||||
} else if (v_type === "SSR") {
|
} else if (v_type === "SSR") {
|
||||||
var v_server = opt.get("address");
|
|
||||||
var v_port = opt.get("port");
|
var v_port = opt.get("port");
|
||||||
var v_protocol = opt.get("ssr_protocol");
|
var v_protocol = opt.get("ssr_protocol");
|
||||||
var v_method = opt.get("ssr_encrypt_method");
|
var v_method = opt.get("ssr_encrypt_method");
|
||||||
|
@ -168,7 +169,7 @@ local has_xray = api.is_finded("xray")
|
||||||
var v_password = opt.get("password");
|
var v_password = opt.get("password");
|
||||||
var v_obfs_param = opt.get("obfs_param");
|
var v_obfs_param = opt.get("obfs_param");
|
||||||
var v_protocol_param = opt.get("protocol_param");
|
var v_protocol_param = opt.get("protocol_param");
|
||||||
var ssr_str = v_server.value + ":" +
|
var ssr_str = _address + ":" +
|
||||||
v_port.value + ":" +
|
v_port.value + ":" +
|
||||||
v_protocol.value + ":" +
|
v_protocol.value + ":" +
|
||||||
v_method.value + ":" +
|
v_method.value + ":" +
|
||||||
|
@ -184,6 +185,7 @@ local has_xray = api.is_finded("xray")
|
||||||
info.v = "2";
|
info.v = "2";
|
||||||
info.ps = v_alias.value;
|
info.ps = v_alias.value;
|
||||||
info.add = opt.get("address").value;
|
info.add = opt.get("address").value;
|
||||||
|
//info.add = _address;
|
||||||
info.port = opt.get("port").value;
|
info.port = opt.get("port").value;
|
||||||
info.id = opt.get("uuid").value;
|
info.id = opt.get("uuid").value;
|
||||||
|
|
||||||
|
@ -196,8 +198,10 @@ local has_xray = api.is_finded("xray")
|
||||||
info.path = opt.get("h2_path").value;
|
info.path = opt.get("h2_path").value;
|
||||||
} else if (v_transport === "tcp") {
|
} else if (v_transport === "tcp") {
|
||||||
info.type = opt.get("tcp_guise").value;
|
info.type = opt.get("tcp_guise").value;
|
||||||
info.host = opt.get("tcp_guise_http_host").value;
|
if (info.type === "http") {
|
||||||
info.path = opt.get("tcp_guise_http_path").value;
|
info.host = opt.get("tcp_guise_http_host").value;
|
||||||
|
info.path = opt.get("tcp_guise_http_path").value;
|
||||||
|
}
|
||||||
} else if (v_transport === "mkcp") {
|
} else if (v_transport === "mkcp") {
|
||||||
v_transport = "kcp";
|
v_transport = "kcp";
|
||||||
info.type = opt.get("mkcp_guise").value;
|
info.type = opt.get("mkcp_guise").value;
|
||||||
|
@ -223,10 +227,9 @@ local has_xray = api.is_finded("xray")
|
||||||
} else if ((v_type === "V2ray" || v_type === "Xray") && opt.get("protocol").value === "vless") {
|
} else if ((v_type === "V2ray" || v_type === "Xray") && opt.get("protocol").value === "vless") {
|
||||||
v_type = "vless";
|
v_type = "vless";
|
||||||
var v_password = opt.get("uuid");
|
var v_password = opt.get("uuid");
|
||||||
var v_server = opt.get("address");
|
|
||||||
var v_port = opt.get("port");
|
var v_port = opt.get("port");
|
||||||
url = encodeURIComponent(v_password.value) +
|
url = encodeURIComponent(v_password.value) +
|
||||||
"@" + v_server.value +
|
"@" + _address +
|
||||||
":" + v_port.value + "?";
|
":" + v_port.value + "?";
|
||||||
|
|
||||||
var params = "";
|
var params = "";
|
||||||
|
@ -235,6 +238,7 @@ local has_xray = api.is_finded("xray")
|
||||||
params += opt.query("host", "ws_host");
|
params += opt.query("host", "ws_host");
|
||||||
params += opt.query("path", "ws_path");
|
params += opt.query("path", "ws_path");
|
||||||
} else if (v_transport === "h2") {
|
} else if (v_transport === "h2") {
|
||||||
|
v_transport = "http";
|
||||||
params += opt.query("host", "h2_host");
|
params += opt.query("host", "h2_host");
|
||||||
params += opt.query("path", "h2_path");
|
params += opt.query("path", "h2_path");
|
||||||
} else if (v_transport === "tcp") {
|
} else if (v_transport === "tcp") {
|
||||||
|
@ -252,21 +256,32 @@ local has_xray = api.is_finded("xray")
|
||||||
//不知道是用path还是serviceName,这里先这样吧
|
//不知道是用path还是serviceName,这里先这样吧
|
||||||
params += opt.query("path", "grpc_serviceName");
|
params += opt.query("path", "grpc_serviceName");
|
||||||
params += opt.query("serviceName", "grpc_serviceName");
|
params += opt.query("serviceName", "grpc_serviceName");
|
||||||
|
params += opt.query("mode", "grpc_mode");
|
||||||
}
|
}
|
||||||
params += "&type=" + v_transport;
|
params += "&type=" + v_transport;
|
||||||
|
|
||||||
params += opt.query("encryption", "encryption");
|
params += opt.query("encryption", "encryption");
|
||||||
if (opt.get("tls").checked) {
|
if (opt.get("tls").checked) {
|
||||||
var v_security = "tls";
|
var v_security = "tls";
|
||||||
params += "&security=" + v_security;
|
if (opt.get("xray_fingerprint") && opt.get("xray_fingerprint").value != "") {
|
||||||
if (opt.get("tlsflow").value) {
|
let v_fp = opt.get("xray_fingerprint").value;
|
||||||
|
params += "&fp=" + v_fp;
|
||||||
|
}
|
||||||
|
if(opt.get("reality") && opt.get("reality").checked) {
|
||||||
|
v_security = "reality";
|
||||||
|
if (opt.get("reality_fingerprint") && opt.get("reality_fingerprint").value != "") {
|
||||||
|
let v_fp = opt.get("reality_fingerprint").value;
|
||||||
|
params += "&fp=" + v_fp;
|
||||||
|
}
|
||||||
|
params += opt.query("pbk", "reality_publicKey");
|
||||||
|
params += opt.query("sid", "reality_shortId");
|
||||||
|
params += opt.query("spx", "reality_spiderX");
|
||||||
|
}
|
||||||
|
if (opt.get("tlsflow") && opt.get("tlsflow").value) {
|
||||||
let v_flow = opt.get("tlsflow").value;
|
let v_flow = opt.get("tlsflow").value;
|
||||||
params += "&flow=" + v_flow;
|
params += "&flow=" + v_flow;
|
||||||
}
|
}
|
||||||
if (opt.get("xray_fingerprint").value && opt.get("xray_fingerprint").value != "") {
|
params += "&security=" + v_security;
|
||||||
let v_fp = opt.get("xray_fingerprint").value
|
|
||||||
params += "&fp=" + v_fp;
|
|
||||||
}
|
|
||||||
params += opt.query("sni", "tls_serverName");
|
params += opt.query("sni", "tls_serverName");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,10 +295,9 @@ local has_xray = api.is_finded("xray")
|
||||||
v_type = "trojan";
|
v_type = "trojan";
|
||||||
}
|
}
|
||||||
var v_password = opt.get("password");
|
var v_password = opt.get("password");
|
||||||
var v_server = opt.get("address");
|
|
||||||
var v_port = opt.get("port");
|
var v_port = opt.get("port");
|
||||||
url = encodeURIComponent(v_password.value) +
|
url = encodeURIComponent(v_password.value) +
|
||||||
"@" + v_server.value +
|
"@" + _address +
|
||||||
":" + v_port.value + "/?";
|
":" + v_port.value + "/?";
|
||||||
var params = "";
|
var params = "";
|
||||||
if (opt.get("tls").checked) {
|
if (opt.get("tls").checked) {
|
||||||
|
@ -300,7 +314,6 @@ local has_xray = api.is_finded("xray")
|
||||||
var url = "";
|
var url = "";
|
||||||
var params = "?";
|
var params = "?";
|
||||||
var v_protocol = opt.get("brook_protocol");
|
var v_protocol = opt.get("brook_protocol");
|
||||||
var v_server = opt.get("address");
|
|
||||||
var v_port = opt.get("port");
|
var v_port = opt.get("port");
|
||||||
var v_password = opt.get("password");
|
var v_password = opt.get("password");
|
||||||
var b_protocol_value = v_protocol.value.split('client').join('server');
|
var b_protocol_value = v_protocol.value.split('client').join('server');
|
||||||
|
@ -319,14 +332,13 @@ local has_xray = api.is_finded("xray")
|
||||||
if (v_path_value.length > 1 && v_path_value.indexOf('/') < 0) {
|
if (v_path_value.length > 1 && v_path_value.indexOf('/') < 0) {
|
||||||
v_path_value = '/' + v_path_value;
|
v_path_value = '/' + v_path_value;
|
||||||
}
|
}
|
||||||
params += "&" + url_protocol + "=" + encodeURIComponent(prefix + v_server.value + ":" + v_port.value + v_path_value);
|
params += "&" + url_protocol + "=" + encodeURIComponent(prefix + _address + ":" + v_port.value + v_path_value);
|
||||||
} else {
|
} else {
|
||||||
params += "&" + url_protocol + "=" + encodeURIComponent(v_server.value + ":" + v_port.value);
|
params += "&" + url_protocol + "=" + encodeURIComponent(_address + ":" + v_port.value);
|
||||||
}
|
}
|
||||||
url += url_protocol;
|
url += url_protocol;
|
||||||
url += params;
|
url += params;
|
||||||
} else if (v_type === "Hysteria") {
|
} else if (v_type === "Hysteria") {
|
||||||
var v_server = opt.get("address");
|
|
||||||
var v_port = opt.get("port");
|
var v_port = opt.get("port");
|
||||||
var params = "";
|
var params = "";
|
||||||
params += opt.query("protocol", "hysteria_protocol");
|
params += opt.query("protocol", "hysteria_protocol");
|
||||||
|
@ -338,7 +350,7 @@ local has_xray = api.is_finded("xray")
|
||||||
params += opt.query("alpn", "hysteria_alpn");
|
params += opt.query("alpn", "hysteria_alpn");
|
||||||
params += opt.query("obfsParam", "hysteria_obfs");
|
params += opt.query("obfsParam", "hysteria_obfs");
|
||||||
var url =
|
var url =
|
||||||
v_server.value + ":" +
|
_address + ":" +
|
||||||
v_port.value + "?" +
|
v_port.value + "?" +
|
||||||
params +
|
params +
|
||||||
"#" + encodeURI(v_alias.value);
|
"#" + encodeURI(v_alias.value);
|
||||||
|
@ -677,6 +689,7 @@ local has_xray = api.is_finded("xray")
|
||||||
if (queryParam.security) {
|
if (queryParam.security) {
|
||||||
if (queryParam.security == "tls") {
|
if (queryParam.security == "tls") {
|
||||||
opt.set('tls', true);
|
opt.set('tls', true);
|
||||||
|
opt.set('reality', false)
|
||||||
opt.set('tlsflow', queryParam.flow || '');
|
opt.set('tlsflow', queryParam.flow || '');
|
||||||
opt.set('tls_serverName', queryParam.sni || '');
|
opt.set('tls_serverName', queryParam.sni || '');
|
||||||
opt.set('tls_allowInsecure', true);
|
opt.set('tls_allowInsecure', true);
|
||||||
|
@ -689,9 +702,24 @@ local has_xray = api.is_finded("xray")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (queryParam.security == "reality") {
|
||||||
|
opt.set('tls', true);
|
||||||
|
opt.set('reality', true)
|
||||||
|
opt.set('tlsflow', queryParam.flow || '');
|
||||||
|
opt.set('tls_serverName', queryParam.sni || '');
|
||||||
|
if (queryParam.fp && queryParam.fp.trim() != "") {
|
||||||
|
opt.set('reality_fingerprint', queryParam.fp);
|
||||||
|
}
|
||||||
|
opt.set('reality_publicKey', queryParam.pbk || '');
|
||||||
|
opt.set('reality_shortId', queryParam.sid || '');
|
||||||
|
opt.set('reality_spiderX', queryParam.spx || '');
|
||||||
|
}
|
||||||
|
|
||||||
queryParam.type = queryParam.type.toLowerCase();
|
queryParam.type = queryParam.type.toLowerCase();
|
||||||
if (queryParam.type === "kcp" || queryParam.type === "mkcp")
|
if (queryParam.type === "kcp" || queryParam.type === "mkcp")
|
||||||
queryParam.type = "mkcp"
|
queryParam.type = "mkcp"
|
||||||
|
if (queryParam.type === "h2" || queryParam.type === "http")
|
||||||
|
queryParam.type = "h2"
|
||||||
opt.set('transport', queryParam.type);
|
opt.set('transport', queryParam.type);
|
||||||
if (queryParam.type === "tcp") {
|
if (queryParam.type === "tcp") {
|
||||||
opt.set('tcp_guise', queryParam.headerType || "none");
|
opt.set('tcp_guise', queryParam.headerType || "none");
|
||||||
|
@ -702,7 +730,7 @@ local has_xray = api.is_finded("xray")
|
||||||
} else if (queryParam.type === "ws") {
|
} else if (queryParam.type === "ws") {
|
||||||
opt.set('ws_host', queryParam.host || "");
|
opt.set('ws_host', queryParam.host || "");
|
||||||
opt.set('ws_path', queryParam.path || "");
|
opt.set('ws_path', queryParam.path || "");
|
||||||
} else if (queryParam.type === "h2") {
|
} else if (queryParam.type === "h2" || queryParam.type === "http") {
|
||||||
opt.set('h2_host', queryParam.host || "");
|
opt.set('h2_host', queryParam.host || "");
|
||||||
opt.set('h2_path', queryParam.path || "");
|
opt.set('h2_path', queryParam.path || "");
|
||||||
} else if (queryParam.type === "quic") {
|
} else if (queryParam.type === "quic") {
|
||||||
|
@ -713,6 +741,7 @@ local has_xray = api.is_finded("xray")
|
||||||
opt.set('mkcp_guise', queryParam.headerType || "none");
|
opt.set('mkcp_guise', queryParam.headerType || "none");
|
||||||
} else if (queryParam.type === "grpc") {
|
} else if (queryParam.type === "grpc") {
|
||||||
opt.set('grpc_serviceName', (queryParam.serviceName || queryParam.path) || "");
|
opt.set('grpc_serviceName', (queryParam.serviceName || queryParam.path) || "");
|
||||||
|
opt.set('grpc_mode', queryParam.mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m.hash) {
|
if (m.hash) {
|
||||||
|
|
|
@ -274,6 +274,15 @@ msgstr "Xray 负载均衡"
|
||||||
msgid "V2ray_balancing"
|
msgid "V2ray_balancing"
|
||||||
msgstr "V2ray 负载均衡"
|
msgstr "V2ray 负载均衡"
|
||||||
|
|
||||||
|
msgid "Balancing Strategy"
|
||||||
|
msgstr "负载均衡策略"
|
||||||
|
|
||||||
|
msgid "Probe Interval"
|
||||||
|
msgstr "探测间隔"
|
||||||
|
|
||||||
|
msgid "The interval between initiating probes. Every time this time elapses, a server status check is performed on a server. The time format is numbers + units, such as '10s', '2h45m', and the supported time units are <code>ns</code>, <code>us</code>, <code>ms</code>, <code>s</code>, <code>m</code>, <code>h</code>, which correspond to nanoseconds, microseconds, milliseconds, seconds, minutes, and hours, respectively."
|
||||||
|
msgstr "发起探测的间隔。每经过这个时间,就会对一个服务器进行服务器状态检测。时间格式为数字+单位,比如<code>"10s"</code>, <code>"2h45m"</code>,支持的时间单位有 <code>ns</code>,<code>us</code>,<code>ms</code>,<code>s</code>,<code>m</code>,<code>h</code>,分别对应纳秒、微秒、毫秒、秒、分、时。"
|
||||||
|
|
||||||
msgid "Shunt"
|
msgid "Shunt"
|
||||||
msgstr "分流"
|
msgstr "分流"
|
||||||
|
|
||||||
|
@ -406,6 +415,9 @@ msgstr "QUIC 连接接收窗口"
|
||||||
msgid "Disable MTU detection"
|
msgid "Disable MTU detection"
|
||||||
msgstr "禁用 MTU 检测"
|
msgstr "禁用 MTU 检测"
|
||||||
|
|
||||||
|
msgid "Lazy Start"
|
||||||
|
msgstr "延迟启动"
|
||||||
|
|
||||||
msgid "Encrypt Method"
|
msgid "Encrypt Method"
|
||||||
msgstr "加密"
|
msgstr "加密"
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,7 @@ config nodes 'myshunt'
|
||||||
option AD 'nil'
|
option AD 'nil'
|
||||||
option BT '_direct'
|
option BT '_direct'
|
||||||
option Netflix 'nil'
|
option Netflix 'nil'
|
||||||
|
option OpenAI 'nil'
|
||||||
option TVB 'nil'
|
option TVB 'nil'
|
||||||
option Proxy '_default'
|
option Proxy '_default'
|
||||||
option China '_direct'
|
option China '_direct'
|
||||||
|
@ -174,6 +175,10 @@ config shunt_rules 'Netflix'
|
||||||
option network 'tcp,udp'
|
option network 'tcp,udp'
|
||||||
option domain_list 'geosite:netflix'
|
option domain_list 'geosite:netflix'
|
||||||
|
|
||||||
|
config shunt_rules 'OpenAI'
|
||||||
|
option remarks 'OpenAI'
|
||||||
|
option domain_list 'geosite:openai'
|
||||||
|
|
||||||
config shunt_rules 'TVB'
|
config shunt_rules 'TVB'
|
||||||
option remarks 'TVB'
|
option remarks 'TVB'
|
||||||
option network 'tcp,udp'
|
option network 'tcp,udp'
|
||||||
|
|
|
@ -893,8 +893,8 @@ acl_app() {
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
pgrep -f /tmp/etc/passwall2/bin > /dev/null 2>&1 && {
|
pgrep -f /tmp/etc/passwall2/bin > /dev/null 2>&1 && {
|
||||||
echolog "程序已启动,无需重复启动!"
|
echolog "程序已启动,先停止再重新启动!"
|
||||||
return 0
|
stop
|
||||||
}
|
}
|
||||||
|
|
||||||
ulimit -n 65535
|
ulimit -n 65535
|
||||||
|
|
|
@ -21,14 +21,10 @@ local geosite_api = ucic:get_first(name, 'global_rules', "geosite_url", "https:/
|
||||||
|
|
||||||
local log = function(...)
|
local log = function(...)
|
||||||
if arg1 then
|
if arg1 then
|
||||||
local result = os.date("%Y-%m-%d %H:%M:%S: ") .. table.concat({...}, " ")
|
|
||||||
if arg1 == "log" then
|
if arg1 == "log" then
|
||||||
local f, err = io.open("/tmp/log/passwall2.log", "a")
|
api.log(...)
|
||||||
if f and err == nil then
|
|
||||||
f:write(result .. "\n")
|
|
||||||
f:close()
|
|
||||||
end
|
|
||||||
elseif arg1 == "print" then
|
elseif arg1 == "print" then
|
||||||
|
local result = os.date("%Y-%m-%d %H:%M:%S: ") .. table.concat({...}, " ")
|
||||||
print(result)
|
print(result)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -80,15 +80,11 @@ local nodeResult = {} -- update result
|
||||||
local debug = false
|
local debug = false
|
||||||
|
|
||||||
local log = function(...)
|
local log = function(...)
|
||||||
local result = os.date("%Y-%m-%d %H:%M:%S: ") .. table.concat({...}, " ")
|
|
||||||
if debug == true then
|
if debug == true then
|
||||||
|
local result = os.date("%Y-%m-%d %H:%M:%S: ") .. table.concat({...}, " ")
|
||||||
print(result)
|
print(result)
|
||||||
else
|
else
|
||||||
local f, err = io.open("/tmp/log/" .. appname .. ".log", "a")
|
api.log(...)
|
||||||
if f and err == nil then
|
|
||||||
f:write(result .. "\n")
|
|
||||||
f:close()
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -328,15 +324,17 @@ local function processData(szType, content, add_mode, add_from)
|
||||||
add_mode = add_mode, --0为手动配置,1为导入,2为订阅
|
add_mode = add_mode, --0为手动配置,1为导入,2为订阅
|
||||||
add_from = add_from
|
add_from = add_from
|
||||||
}
|
}
|
||||||
|
--ssr://base64(host:port:protocol:method:obfs:base64pass/?obfsparam=base64param&protoparam=base64param&remarks=base64remarks&group=base64group&udpport=0&uot=0)
|
||||||
if szType == 'ssr' then
|
if szType == 'ssr' then
|
||||||
|
result.type = "SSR"
|
||||||
|
|
||||||
local dat = split(content, "/%?")
|
local dat = split(content, "/%?")
|
||||||
local hostInfo = split(dat[1], ':')
|
local hostInfo = split(dat[1], ':')
|
||||||
result.type = "SSR"
|
if dat[1]:match('%[(.*)%]') then
|
||||||
result.address = ""
|
result.address = dat[1]:match('%[(.*)%]')
|
||||||
for i=1,#hostInfo-5,1 do
|
else
|
||||||
result.address = result.address .. hostInfo[i] .. ":"
|
result.address = hostInfo[#hostInfo-5]
|
||||||
end
|
end
|
||||||
result.address = string.sub(result.address, 0, #result.address-1)
|
|
||||||
result.port = hostInfo[#hostInfo-4]
|
result.port = hostInfo[#hostInfo-4]
|
||||||
result.protocol = hostInfo[#hostInfo-3]
|
result.protocol = hostInfo[#hostInfo-3]
|
||||||
result.method = hostInfo[#hostInfo-2]
|
result.method = hostInfo[#hostInfo-2]
|
||||||
|
@ -410,6 +408,15 @@ local function processData(szType, content, add_mode, add_from)
|
||||||
result.tls = "0"
|
result.tls = "0"
|
||||||
end
|
end
|
||||||
elseif szType == "ss" then
|
elseif szType == "ss" then
|
||||||
|
result.type = "SS"
|
||||||
|
|
||||||
|
--SS-URI = "ss://" userinfo "@" hostname ":" port [ "/" ] [ "?" plugin ] [ "#" tag ]
|
||||||
|
--userinfo = websafe-base64-encode-utf8(method ":" password)
|
||||||
|
--ss://YWVzLTEyOC1nY206dGVzdA@192.168.100.1:8888#Example1
|
||||||
|
--ss://cmM0LW1kNTpwYXNzd2Q@192.168.100.1:8888/?plugin=obfs-local%3Bobfs%3Dhttp#Example2
|
||||||
|
--ss://2022-blake3-aes-256-gcm:YctPZ6U7xPPcU%2Bgp3u%2B0tx%2FtRizJN9K8y%2BuKlW2qjlI%3D@192.168.100.1:8888#Example3
|
||||||
|
--ss://2022-blake3-aes-256-gcm:YctPZ6U7xPPcU%2Bgp3u%2B0tx%2FtRizJN9K8y%2BuKlW2qjlI%3D@192.168.100.1:8888/?plugin=v2ray-plugin%3Bserver#Example3
|
||||||
|
|
||||||
local idx_sp = 0
|
local idx_sp = 0
|
||||||
local alias = ""
|
local alias = ""
|
||||||
if content:find("#") then
|
if content:find("#") then
|
||||||
|
@ -418,28 +425,9 @@ local function processData(szType, content, add_mode, add_from)
|
||||||
end
|
end
|
||||||
result.remarks = UrlDecode(alias)
|
result.remarks = UrlDecode(alias)
|
||||||
local info = content:sub(1, idx_sp - 1)
|
local info = content:sub(1, idx_sp - 1)
|
||||||
local hostInfo = split(base64Decode(info), "@")
|
if info:find("/%?") then
|
||||||
local hostInfoLen = #hostInfo
|
local find_index = info:find("/%?")
|
||||||
local host = nil
|
local query = split(info, "/%?")
|
||||||
local userinfo = nil
|
|
||||||
if hostInfoLen > 2 then
|
|
||||||
host = split(hostInfo[hostInfoLen], ":")
|
|
||||||
userinfo = {}
|
|
||||||
for i = 1, hostInfoLen - 1 do
|
|
||||||
tinsert(userinfo, hostInfo[i])
|
|
||||||
end
|
|
||||||
userinfo = table.concat(userinfo, '@')
|
|
||||||
else
|
|
||||||
host = split(hostInfo[2], ":")
|
|
||||||
userinfo = base64Decode(hostInfo[1])
|
|
||||||
end
|
|
||||||
local method = userinfo:sub(1, userinfo:find(":") - 1)
|
|
||||||
local password = userinfo:sub(userinfo:find(":") + 1, #userinfo)
|
|
||||||
result.type = "SS"
|
|
||||||
result.address = host[1]
|
|
||||||
if host[2] and host[2]:find("/%?") then
|
|
||||||
local query = split(host[2], "/%?")
|
|
||||||
result.port = query[1]
|
|
||||||
local params = {}
|
local params = {}
|
||||||
for _, v in pairs(split(query[2], '&')) do
|
for _, v in pairs(split(query[2], '&')) do
|
||||||
local t = split(v, '=')
|
local t = split(v, '=')
|
||||||
|
@ -459,39 +447,70 @@ local function processData(szType, content, add_mode, add_from)
|
||||||
if result.plugin and result.plugin == "simple-obfs" then
|
if result.plugin and result.plugin == "simple-obfs" then
|
||||||
result.plugin = "obfs-local"
|
result.plugin = "obfs-local"
|
||||||
end
|
end
|
||||||
else
|
info = info:sub(1, find_index - 1)
|
||||||
result.port = host[2]
|
|
||||||
end
|
end
|
||||||
result.method = method
|
|
||||||
result.password = password
|
|
||||||
|
|
||||||
local aead = false
|
local hostInfo = split(base64Decode(info), "@")
|
||||||
for k, v in ipairs({"aes-128-gcm", "aes-256-gcm", "chacha20-poly1305", "chacha20-ietf-poly1305"}) do
|
if hostInfo and #hostInfo > 0 then
|
||||||
if method:lower() == v:lower() then
|
local host_port = hostInfo[#hostInfo]
|
||||||
aead = true
|
-- [2001:4860:4860::8888]:443
|
||||||
|
-- 8.8.8.8:443
|
||||||
|
if host_port:find(":") then
|
||||||
|
local sp = split(host_port, ":")
|
||||||
|
result.port = sp[#sp]
|
||||||
|
if api.is_ipv6addrport(host_port) then
|
||||||
|
result.address = api.get_ipv6_only(host_port)
|
||||||
|
else
|
||||||
|
result.address = sp[1]
|
||||||
|
end
|
||||||
|
else
|
||||||
|
result.address = host_port
|
||||||
end
|
end
|
||||||
end
|
|
||||||
if aead then
|
local userinfo = nil
|
||||||
if ss_aead_type_default == "shadowsocks-libev" and has_ss then
|
if #hostInfo > 2 then
|
||||||
result.type = "SS"
|
userinfo = {}
|
||||||
elseif ss_aead_type_default == "shadowsocks-rust" and has_ss_rust then
|
for i = 1, #hostInfo - 1 do
|
||||||
result.type = 'SS-Rust'
|
tinsert(userinfo, hostInfo[i])
|
||||||
if method:lower() == "chacha20-poly1305" then
|
|
||||||
result.method = "chacha20-ietf-poly1305"
|
|
||||||
end
|
end
|
||||||
elseif ss_aead_type_default == "v2ray" and has_v2ray and not result.plugin then
|
userinfo = table.concat(userinfo, '@')
|
||||||
result.type = 'V2ray'
|
else
|
||||||
result.protocol = 'shadowsocks'
|
userinfo = base64Decode(hostInfo[1])
|
||||||
result.transport = 'tcp'
|
end
|
||||||
if method:lower() == "chacha20-ietf-poly1305" then
|
|
||||||
result.method = "chacha20-poly1305"
|
local method = userinfo:sub(1, userinfo:find(":") - 1)
|
||||||
|
local password = userinfo:sub(userinfo:find(":") + 1, #userinfo)
|
||||||
|
result.method = method
|
||||||
|
result.password = password
|
||||||
|
|
||||||
|
local aead = false
|
||||||
|
for k, v in ipairs({"aes-128-gcm", "aes-256-gcm", "chacha20-poly1305", "chacha20-ietf-poly1305"}) do
|
||||||
|
if method:lower() == v:lower() then
|
||||||
|
aead = true
|
||||||
end
|
end
|
||||||
elseif ss_aead_type_default == "xray" and has_xray and not result.plugin then
|
end
|
||||||
result.type = 'Xray'
|
if aead then
|
||||||
result.protocol = 'shadowsocks'
|
if ss_aead_type_default == "shadowsocks-libev" and has_ss then
|
||||||
result.transport = 'tcp'
|
result.type = "SS"
|
||||||
if method:lower() == "chacha20-ietf-poly1305" then
|
elseif ss_aead_type_default == "shadowsocks-rust" and has_ss_rust then
|
||||||
result.method = "chacha20-poly1305"
|
result.type = 'SS-Rust'
|
||||||
|
if method:lower() == "chacha20-poly1305" then
|
||||||
|
result.method = "chacha20-ietf-poly1305"
|
||||||
|
end
|
||||||
|
elseif ss_aead_type_default == "v2ray" and has_v2ray and not result.plugin then
|
||||||
|
result.type = 'V2ray'
|
||||||
|
result.protocol = 'shadowsocks'
|
||||||
|
result.transport = 'tcp'
|
||||||
|
if method:lower() == "chacha20-ietf-poly1305" then
|
||||||
|
result.method = "chacha20-poly1305"
|
||||||
|
end
|
||||||
|
elseif ss_aead_type_default == "xray" and has_xray and not result.plugin then
|
||||||
|
result.type = 'Xray'
|
||||||
|
result.protocol = 'shadowsocks'
|
||||||
|
result.transport = 'tcp'
|
||||||
|
if method:lower() == "chacha20-ietf-poly1305" then
|
||||||
|
result.method = "chacha20-poly1305"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -513,33 +532,28 @@ local function processData(szType, content, add_mode, add_from)
|
||||||
result.password = UrlDecode(Info[1])
|
result.password = UrlDecode(Info[1])
|
||||||
local port = "443"
|
local port = "443"
|
||||||
Info[2] = (Info[2] or ""):gsub("/%?", "?")
|
Info[2] = (Info[2] or ""):gsub("/%?", "?")
|
||||||
local hostInfo = nil
|
|
||||||
if Info[2]:find(":") then
|
|
||||||
hostInfo = split(Info[2], ":")
|
|
||||||
result.address = hostInfo[1]
|
|
||||||
local idx_port = 2
|
|
||||||
if hostInfo[2]:find("?") then
|
|
||||||
hostInfo = split(hostInfo[2], "?")
|
|
||||||
idx_port = 1
|
|
||||||
end
|
|
||||||
if hostInfo[idx_port] ~= "" then port = hostInfo[idx_port] end
|
|
||||||
else
|
|
||||||
if Info[2]:find("?") then
|
|
||||||
hostInfo = split(Info[2], "?")
|
|
||||||
end
|
|
||||||
result.address = hostInfo and hostInfo[1] or Info[2]
|
|
||||||
end
|
|
||||||
local peer, sni = nil, ""
|
|
||||||
local allowInsecure = allowInsecure_default
|
|
||||||
local query = split(Info[2], "?")
|
local query = split(Info[2], "?")
|
||||||
|
local host_port = query[1]
|
||||||
local params = {}
|
local params = {}
|
||||||
for _, v in pairs(split(query[2], '&')) do
|
for _, v in pairs(split(query[2], '&')) do
|
||||||
local t = split(v, '=')
|
local t = split(v, '=')
|
||||||
params[string.lower(t[1])] = UrlDecode(t[2])
|
params[string.lower(t[1])] = UrlDecode(t[2])
|
||||||
end
|
end
|
||||||
if params.allowinsecure then
|
-- [2001:4860:4860::8888]:443
|
||||||
allowInsecure = params.allowinsecure
|
-- 8.8.8.8:443
|
||||||
|
if host_port:find(":") then
|
||||||
|
local sp = split(host_port, ":")
|
||||||
|
port = sp[#sp]
|
||||||
|
if api.is_ipv6addrport(host_port) then
|
||||||
|
result.address = api.get_ipv6_only(host_port)
|
||||||
|
else
|
||||||
|
result.address = sp[1]
|
||||||
|
end
|
||||||
|
else
|
||||||
|
result.address = host_port
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local peer, sni = nil, ""
|
||||||
if params.peer then peer = params.peer end
|
if params.peer then peer = params.peer end
|
||||||
sni = params.sni and params.sni or ""
|
sni = params.sni and params.sni or ""
|
||||||
if params.ws and params.ws == "1" then
|
if params.ws and params.ws == "1" then
|
||||||
|
@ -551,7 +565,16 @@ local function processData(szType, content, add_mode, add_from)
|
||||||
result.port = port
|
result.port = port
|
||||||
result.tls = '1'
|
result.tls = '1'
|
||||||
result.tls_serverName = peer and peer or sni
|
result.tls_serverName = peer and peer or sni
|
||||||
result.tls_allowInsecure = allowInsecure and "1" or "0"
|
if params.allowinsecure then
|
||||||
|
if params.allowinsecure == "1" or params.allowinsecure == "0" then
|
||||||
|
result.tls_allowInsecure = params.allowinsecure
|
||||||
|
else
|
||||||
|
result.tls_allowInsecure = string.lower(params.allowinsecure) == "true" and "1" or "0"
|
||||||
|
end
|
||||||
|
--log(result.remarks .. ' 使用节点AllowInsecure设定: '.. result.tls_allowInsecure)
|
||||||
|
else
|
||||||
|
result.tls_allowInsecure = allowInsecure_default and "1" or "0"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
elseif szType == "ssd" then
|
elseif szType == "ssd" then
|
||||||
result.type = "SS"
|
result.type = "SS"
|
||||||
|
@ -581,36 +604,34 @@ local function processData(szType, content, add_mode, add_from)
|
||||||
result.uuid = UrlDecode(Info[1])
|
result.uuid = UrlDecode(Info[1])
|
||||||
local port = "443"
|
local port = "443"
|
||||||
Info[2] = (Info[2] or ""):gsub("/%?", "?")
|
Info[2] = (Info[2] or ""):gsub("/%?", "?")
|
||||||
local hostInfo = nil
|
|
||||||
if Info[2]:find(":") then
|
|
||||||
hostInfo = split(Info[2], ":")
|
|
||||||
result.address = hostInfo[1]
|
|
||||||
local idx_port = 2
|
|
||||||
if hostInfo[2]:find("?") then
|
|
||||||
hostInfo = split(hostInfo[2], "?")
|
|
||||||
idx_port = 1
|
|
||||||
end
|
|
||||||
if hostInfo[idx_port] ~= "" then port = hostInfo[idx_port] end
|
|
||||||
else
|
|
||||||
if Info[2]:find("?") then
|
|
||||||
hostInfo = split(Info[2], "?")
|
|
||||||
end
|
|
||||||
result.address = hostInfo and hostInfo[1] or Info[2]
|
|
||||||
end
|
|
||||||
|
|
||||||
local query = split(Info[2], "?")
|
local query = split(Info[2], "?")
|
||||||
|
local host_port = query[1]
|
||||||
local params = {}
|
local params = {}
|
||||||
for _, v in pairs(split(query[2], '&')) do
|
for _, v in pairs(split(query[2], '&')) do
|
||||||
local t = split(v, '=')
|
local t = split(v, '=')
|
||||||
params[t[1]] = UrlDecode(t[2])
|
params[t[1]] = UrlDecode(t[2])
|
||||||
end
|
end
|
||||||
|
-- [2001:4860:4860::8888]:443
|
||||||
|
-- 8.8.8.8:443
|
||||||
|
if host_port:find(":") then
|
||||||
|
local sp = split(host_port, ":")
|
||||||
|
port = sp[#sp]
|
||||||
|
if api.is_ipv6addrport(host_port) then
|
||||||
|
result.address = api.get_ipv6_only(host_port)
|
||||||
|
else
|
||||||
|
result.address = sp[1]
|
||||||
|
end
|
||||||
|
else
|
||||||
|
result.address = host_port
|
||||||
|
end
|
||||||
|
|
||||||
params.type = string.lower(params.type)
|
params.type = string.lower(params.type)
|
||||||
if params.type == 'ws' then
|
if params.type == 'ws' then
|
||||||
result.ws_host = params.host
|
result.ws_host = params.host
|
||||||
result.ws_path = params.path
|
result.ws_path = params.path
|
||||||
end
|
end
|
||||||
if params.type == 'h2' then
|
if params.type == 'h2' or params.type == 'http' then
|
||||||
|
params.type = "h2"
|
||||||
result.h2_host = params.host
|
result.h2_host = params.host
|
||||||
result.h2_path = params.path
|
result.h2_path = params.path
|
||||||
end
|
end
|
||||||
|
@ -637,17 +658,24 @@ local function processData(szType, content, add_mode, add_from)
|
||||||
if params.type == 'grpc' then
|
if params.type == 'grpc' then
|
||||||
if params.path then result.grpc_serviceName = params.path end
|
if params.path then result.grpc_serviceName = params.path end
|
||||||
if params.serviceName then result.grpc_serviceName = params.serviceName end
|
if params.serviceName then result.grpc_serviceName = params.serviceName end
|
||||||
|
result.grpc_mode = params.mode
|
||||||
end
|
end
|
||||||
result.transport = params.type
|
result.transport = params.type
|
||||||
|
|
||||||
result.encryption = params.encryption or "none"
|
result.encryption = params.encryption or "none"
|
||||||
|
|
||||||
result.tls = "0"
|
result.tls = "0"
|
||||||
if params.security == "tls" then
|
if params.security == "tls" or params.security == "reality" then
|
||||||
result.tls = "1"
|
result.tls = "1"
|
||||||
result.tlsflow = params.flow or nil
|
result.tlsflow = params.flow or nil
|
||||||
result.tls_serverName = (params.sni and params.sni ~= "") and params.sni or params.host
|
result.tls_serverName = (params.sni and params.sni ~= "") and params.sni or params.host
|
||||||
result.fingerprint = (params.fp and params.fp ~= "") and params.fp or "chrome"
|
result.fingerprint = (params.fp and params.fp ~= "") and params.fp or "chrome"
|
||||||
|
if params.security == "reality" then
|
||||||
|
result.reality = "1"
|
||||||
|
result.reality_publicKey = params.pbk or nil
|
||||||
|
result.reality_shortId = params.sid or nil
|
||||||
|
result.reality_spiderX = params.spx or nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
result.port = port
|
result.port = port
|
||||||
|
@ -664,9 +692,7 @@ local function processData(szType, content, add_mode, add_from)
|
||||||
result.type = "Hysteria"
|
result.type = "Hysteria"
|
||||||
|
|
||||||
local dat = split(content, '%?')
|
local dat = split(content, '%?')
|
||||||
local hostInfo = split(dat[1], ':')
|
local host_port = dat[1]
|
||||||
result.address = hostInfo[1]
|
|
||||||
result.port = hostInfo[2]
|
|
||||||
local params = {}
|
local params = {}
|
||||||
for _, v in pairs(split(dat[2], '&')) do
|
for _, v in pairs(split(dat[2], '&')) do
|
||||||
local t = split(v, '=')
|
local t = split(v, '=')
|
||||||
|
@ -674,6 +700,19 @@ local function processData(szType, content, add_mode, add_from)
|
||||||
params[t[1]] = t[2]
|
params[t[1]] = t[2]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
-- [2001:4860:4860::8888]:443
|
||||||
|
-- 8.8.8.8:443
|
||||||
|
if host_port:find(":") then
|
||||||
|
local sp = split(host_port, ":")
|
||||||
|
result.port = sp[#sp]
|
||||||
|
if api.is_ipv6addrport(host_port) then
|
||||||
|
result.address = api.get_ipv6_only(host_port)
|
||||||
|
else
|
||||||
|
result.address = sp[1]
|
||||||
|
end
|
||||||
|
else
|
||||||
|
result.address = host_port
|
||||||
|
end
|
||||||
result.protocol = params.protocol
|
result.protocol = params.protocol
|
||||||
result.hysteria_obfs = params.obfsParam
|
result.hysteria_obfs = params.obfsParam
|
||||||
result.hysteria_auth_type = "string"
|
result.hysteria_auth_type = "string"
|
||||||
|
@ -990,8 +1029,8 @@ local function parse_link(raw, add_mode, add_from)
|
||||||
if result then
|
if result then
|
||||||
if not result.type then
|
if not result.type then
|
||||||
log('丢弃节点:' .. result.remarks .. ",找不到可使用二进制.")
|
log('丢弃节点:' .. result.remarks .. ",找不到可使用二进制.")
|
||||||
elseif (add_mode == "2" and is_filter_keyword(result.remarks)) or not result.address or result.remarks == "NULL" or result.address=="127.0.0.1" or
|
elseif (add_mode == "2" and is_filter_keyword(result.remarks)) or not result.address or result.remarks == "NULL" or result.address == "127.0.0.1" or
|
||||||
(not datatypes.hostname(result.address) and not (datatypes.ipmask4(result.address) or datatypes.ipmask6(result.address))) then
|
(not datatypes.hostname(result.address) and not (api.is_ip(result.address))) then
|
||||||
log('丢弃过滤节点: ' .. result.type .. ' 节点, ' .. result.remarks)
|
log('丢弃过滤节点: ' .. result.type .. ' 节点, ' .. result.remarks)
|
||||||
else
|
else
|
||||||
tinsert(node_list, result)
|
tinsert(node_list, result)
|
||||||
|
|
|
@ -9,10 +9,13 @@ LUCI_TITLE:=LuCI support for quickstart
|
||||||
LUCI_DEPENDS:=+quickstart +luci-app-store
|
LUCI_DEPENDS:=+quickstart +luci-app-store
|
||||||
LUCI_PKGARCH:=all
|
LUCI_PKGARCH:=all
|
||||||
|
|
||||||
PKG_VERSION:=0.6.9-4
|
PKG_VERSION:=0.7.2-1
|
||||||
# PKG_RELEASE MUST be empty for luci.mk
|
# PKG_RELEASE MUST be empty for luci.mk
|
||||||
PKG_RELEASE:=
|
PKG_RELEASE:=
|
||||||
|
|
||||||
|
LUCI_MINIFY_CSS:=0
|
||||||
|
LUCI_MINIFY_JS:=0
|
||||||
|
|
||||||
include $(TOPDIR)/feeds/luci/luci.mk
|
include $(TOPDIR)/feeds/luci/luci.mk
|
||||||
|
|
||||||
# call BuildPackage - OpenWrt buildroot signature
|
# call BuildPackage - OpenWrt buildroot signature
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -10,11 +10,11 @@ include $(TOPDIR)/rules.mk
|
||||||
PKG_ARCH_quickstart:=$(ARCH)
|
PKG_ARCH_quickstart:=$(ARCH)
|
||||||
|
|
||||||
PKG_NAME:=quickstart
|
PKG_NAME:=quickstart
|
||||||
PKG_VERSION:=0.6.11
|
PKG_VERSION:=0.7.3
|
||||||
PKG_RELEASE:=2
|
PKG_RELEASE:=1
|
||||||
PKG_SOURCE:=$(PKG_NAME)-binary-$(PKG_VERSION).tar.gz
|
PKG_SOURCE:=$(PKG_NAME)-binary-$(PKG_VERSION).tar.gz
|
||||||
PKG_SOURCE_URL:=https://fw.koolcenter.com/binary/quickstart/
|
PKG_SOURCE_URL:=https://fw.koolcenter.com/binary/quickstart/
|
||||||
PKG_HASH:=f6cbc4a8dab3c5e659b45ffda617df94ea81cf5e9e07dbe88183036167b9bfb5
|
PKG_HASH:=65c14deccf7afb8179a347e31a6f1e5d20333e7b01f9003837abae15c3955ada
|
||||||
|
|
||||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-binary-$(PKG_VERSION)
|
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-binary-$(PKG_VERSION)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue