mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-09-10 18:34:18 +08:00
🎄 Sync 2026-08-10 20:58:00
This commit is contained in:
+2
-2
@@ -6,9 +6,9 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=dae
|
||||
PKG_VERSION:=2026.08.05
|
||||
PKG_RELEASE:=33
|
||||
PKG_RELEASE:=34
|
||||
|
||||
PKG_SOURCE:=dae-src-2026.08.05-479f43645df5.tar.gz
|
||||
PKG_SOURCE:=dae-src-2026.08.05-fc1a5bf558fd.tar.gz
|
||||
PKG_SOURCE_URL:=https://github.com/kenzok8/openwrt-daede/releases/download/dae-src
|
||||
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
|
||||
PKG_HASH:=skip
|
||||
|
||||
+2
-2
@@ -6,9 +6,9 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=daed
|
||||
PKG_VERSION:=2026.08.05
|
||||
PKG_RELEASE:=44
|
||||
PKG_RELEASE:=45
|
||||
|
||||
PKG_SOURCE:=daed-src-2026.08.05-c389546b8c1f.tar.gz
|
||||
PKG_SOURCE:=daed-src-2026.08.05-1d87c2949acc.tar.gz
|
||||
PKG_SOURCE_URL:=https://github.com/kenzok8/openwrt-daede/releases/download/daed-src
|
||||
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
|
||||
PKG_HASH:=skip
|
||||
|
||||
@@ -1048,6 +1048,15 @@ return view.extend({
|
||||
so.depends({type: /^(zerotier|wireguard|masque|openvpn)$/});
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.ListValue, 'ipstack_congestion_controller', _('IP stack') + ': ' + _('Congestion controller'));
|
||||
so.value('', _('Keep default'));
|
||||
so.value('cubic', _('cubic'));
|
||||
so.value('reno', _('reno'));
|
||||
so.value('bbr', _('bbr'));
|
||||
so.value('bbr3', _('bbr3'));
|
||||
so.depends({ipstack: /^(auto|mips)$/}); // not empty not gvisor
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.ListValue, 'congestion_controller', _('Congestion controller'));
|
||||
so.default = hm.congestion_controller[0][0];
|
||||
hm.congestion_controller.forEach((res) => {
|
||||
@@ -1055,7 +1064,6 @@ return view.extend({
|
||||
})
|
||||
so.depends({type: /^(tuic|shadowquic|trusttunnel)$/});
|
||||
so.depends({type: 'masque', masque_network: /^(|h3-l4proxy)$/});
|
||||
so.depends({ipstack: /^(auto|mips)$/}); // not empty not gvisor
|
||||
so.modalonly = true;
|
||||
|
||||
so = ss.taboption('field_general', form.ListValue, 'bbr_profile', _('BBR profile'));
|
||||
|
||||
@@ -171,6 +171,14 @@ migrate() {
|
||||
uci_remove "$CONF" "$1" zerotier_ipstack
|
||||
uci_set "$CONF" "$1" ipstack "$zerotier_ipstack"
|
||||
fi
|
||||
|
||||
# congestion_controller -> ipstack_congestion_controller
|
||||
if isDefined "$1" congestion_controller && (isDefined "$1" zerotier_ipstack || isDefined "$1" ipstack); then
|
||||
local congestion_controller
|
||||
config_get congestion_controller "$1" congestion_controller ""
|
||||
uci_remove "$CONF" "$1" congestion_controller
|
||||
uci_set "$CONF" "$1" ipstack_congestion_controller "$congestion_controller"
|
||||
fi
|
||||
}
|
||||
|
||||
config_foreach migrate node
|
||||
|
||||
@@ -678,12 +678,12 @@ uci.foreach(uciconf, ucinode, (cfg) => {
|
||||
/* Extra fields */
|
||||
"ip-stack": cfg.ipstack ? {
|
||||
mode: cfg.ipstack,
|
||||
"congestion-controller": replace(cfg.congestion_controller, 'new_reno', 'reno')
|
||||
"congestion-controller": cfg.ipstack_congestion_controller
|
||||
} : null,
|
||||
"udp-over-stream": strToBool(cfg.shadowquic_udp_over_stream || cfg.tuic_udp_over_stream),
|
||||
"heartbeat-interval": strToInt(cfg.tuic_heartbeat) || null,
|
||||
"keep-alive-interval": strToInt(cfg.shadowquic_heartbeat) || null,
|
||||
"congestion-controller": cfg.type in ['zerotier', 'wireguard', 'masque', 'openvpn'] ? null : cfg.congestion_controller,
|
||||
"congestion-controller": cfg.congestion_controller,
|
||||
"bbr-profile": cfg.bbr_profile,
|
||||
"max-open-streams": strToInt(cfg.max_open_streams) || null,
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ LUCI_TITLE:=Information dashboard for 3G/LTE dongle
|
||||
LUCI_DEPENDS:=+modeminfo
|
||||
PKG_LICENSE:=GPLv3
|
||||
PKG_VERSION:=0.4.8
|
||||
PKG_RELEASE:=11
|
||||
PKG_RELEASE:=12
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ Supported devices:
|
||||
|
||||
- Sierra Wireless EM7455/EM9191
|
||||
|
||||
- HP LT4220
|
||||
- Telit LN940(HP LT4220)/LM960
|
||||
|
||||
- Dell DW5821e/DW5829e
|
||||
|
||||
@@ -43,7 +43,7 @@ Supported devices:
|
||||
|modeminfo |common files |
|
||||
|modeminfo-qmi |Qualcomm MSM Interface support |
|
||||
|modeminfo-serial-quectel |Quectel modems support |
|
||||
|modeminfo-serial-telit |Telit LN940 (HP LT4220) modem support |
|
||||
|modeminfo-serial-telit |Telit LN940(HP LT4220)/LM960 modem support |
|
||||
|modeminfo-serial-huawei |Huawei MU709/ME909/E3372(stick mode, LTE only) modems support|
|
||||
|modeminfo-serial-sierra |Sierra EM7455/EM9191 modem support |
|
||||
|modeminfo-serial-simcom |SimCOM modems support |
|
||||
|
||||
@@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-passwall
|
||||
PKG_VERSION:=26.8.1
|
||||
PKG_RELEASE:=211
|
||||
PKG_RELEASE:=212
|
||||
PKG_PO_VERSION:=$(PKG_VERSION)
|
||||
|
||||
PKG_CONFIG_DEPENDS:= \
|
||||
|
||||
@@ -49,18 +49,6 @@ m.uci:foreach(appname, "socks", function(s)
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
local dynamicList_write = function(self, section, value)
|
||||
local new_t = {}
|
||||
if type(value) == "table" then
|
||||
new_t = api.table_remove_duplicates(value)
|
||||
else
|
||||
new_t = { value }
|
||||
end
|
||||
local new_val = table.concat(new_t, " ")
|
||||
return DynamicList.write(self, section, new_val)
|
||||
end
|
||||
|
||||
-- [[ ACLs Settings ]]--
|
||||
s = m:section(NamedSection, cfgid, translate("ACLs"), translate("ACLs"))
|
||||
s.addremove = false
|
||||
@@ -173,7 +161,6 @@ sources.validate = function(self, value, t)
|
||||
|
||||
return value
|
||||
end
|
||||
sources.write = dynamicList_write
|
||||
|
||||
o = s:option(ListValue, "mode", translate("Mode"))
|
||||
o:value("0", translate("No Proxy"))
|
||||
|
||||
@@ -372,15 +372,6 @@ if api.is_finded("smartdns") then
|
||||
o.cfgvalue = function(self, section)
|
||||
return m:get(section, self.option) or {"tcp://1.1.1.1"}
|
||||
end
|
||||
function o.write(self, section, value)
|
||||
local new_t = {}
|
||||
if type(value) == "table" then
|
||||
new_t = api.table_remove_duplicates(value)
|
||||
else
|
||||
new_t = { value }
|
||||
end
|
||||
return DynamicList.write(self, section, new_t)
|
||||
end
|
||||
end
|
||||
|
||||
o = s:taboption("DNS", ListValue, "xray_dns_mode", translate("Remote DNS") .. " " .. translate("Request protocol"))
|
||||
|
||||
@@ -156,6 +156,12 @@ o:value("UseIPv6v4", translate("Prefer IPv6"))
|
||||
o:value("UseIPv4", translate("IPv4 Only"))
|
||||
o:value("UseIPv6", translate("IPv6 Only"))
|
||||
|
||||
o = s:option(Flag, "allowInsecure", translate("allowInsecure"))
|
||||
o.default = "0"
|
||||
o.rmempty = false
|
||||
o.description = translate("Whether unsafe connections are allowed. When checked, Certificate validation will be skipped.") .. "<br>" ..
|
||||
translate("Used when the node link does not include this parameter.")
|
||||
|
||||
o = s:option(ListValue, "filter_keyword_mode", translate("Filter keyword Mode"))
|
||||
o.default = "5"
|
||||
o:value("0", translate("Close"))
|
||||
|
||||
@@ -164,19 +164,6 @@ source.validate = function(self, value, t)
|
||||
return value
|
||||
end
|
||||
|
||||
local dynamicList_write = function(self, section, value)
|
||||
local new_t = {}
|
||||
if type(value) == "table" then
|
||||
new_t = api.table_remove_duplicates(value)
|
||||
else
|
||||
new_t = { value }
|
||||
end
|
||||
local new_val = table.concat(new_t, " ")
|
||||
return DynamicList.write(self, section, new_val)
|
||||
end
|
||||
|
||||
source.write = dynamicList_write
|
||||
|
||||
--[[
|
||||
-- Too low usage rate, hidden
|
||||
sourcePort = s:option(Value, "sourcePort", translate("Source port"))
|
||||
|
||||
@@ -116,12 +116,12 @@ if load_balancing_options then -- [[ Load balancing Start ]]
|
||||
end
|
||||
end
|
||||
-- 读取旧 DynamicList
|
||||
function o.cfgvalue(self, section)
|
||||
return m.uci:get_list(appname, section, "balancing_node") or {}
|
||||
function o.custom_cfgvalue(self, section)
|
||||
return table.concat(m:get(section, "balancing_node") or {}, " ")
|
||||
end
|
||||
-- 写入保持 DynamicList
|
||||
function o.custom_write(self, section, value)
|
||||
local old = m.uci:get_list(appname, section, "balancing_node") or {}
|
||||
local old = m:get(section, "balancing_node") or {}
|
||||
local new, set = {}, {}
|
||||
for v in value:gmatch("%S+") do
|
||||
new[#new + 1] = v
|
||||
@@ -129,13 +129,13 @@ if load_balancing_options then -- [[ Load balancing Start ]]
|
||||
end
|
||||
for _, v in ipairs(old) do
|
||||
if not set[v] then
|
||||
m.uci:set_list(appname, section, "balancing_node", new)
|
||||
m:set(section, "balancing_node", new)
|
||||
return
|
||||
end
|
||||
set[v] = nil
|
||||
end
|
||||
for _ in pairs(set) do
|
||||
m.uci:set_list(appname, section, "balancing_node", new)
|
||||
m:set(section, "balancing_node", new)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
@@ -115,12 +115,12 @@ if load_urltest_options then -- [[ URLTest Start ]]
|
||||
end
|
||||
end
|
||||
-- 读取旧 DynamicList
|
||||
function o.cfgvalue(self, section)
|
||||
return m.uci:get_list(appname, section, "urltest_node") or {}
|
||||
function o.custom_cfgvalue(self, section)
|
||||
return table.concat(m:get(section, "urltest_node") or {}, " ")
|
||||
end
|
||||
-- 写入保持 DynamicList
|
||||
function o.custom_write(self, section, value)
|
||||
local old = m.uci:get_list(appname, section, "urltest_node") or {}
|
||||
local old = m:get(section, "urltest_node") or {}
|
||||
local new, set = {}, {}
|
||||
for v in value:gmatch("%S+") do
|
||||
new[#new + 1] = v
|
||||
@@ -128,13 +128,13 @@ if load_urltest_options then -- [[ URLTest Start ]]
|
||||
end
|
||||
for _, v in ipairs(old) do
|
||||
if not set[v] then
|
||||
m.uci:set_list(appname, section, "urltest_node", new)
|
||||
m:set(section, "urltest_node", new)
|
||||
return
|
||||
end
|
||||
set[v] = nil
|
||||
end
|
||||
for _ in pairs(set) do
|
||||
m.uci:set_list(appname, section, "urltest_node", new)
|
||||
m:set(section, "urltest_node", new)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
@@ -216,15 +216,6 @@ o:depends({ [_n("reality")] = true })
|
||||
|
||||
o = s:option(DynamicList, _n("reality_serverNames"), translate("serverNames"))
|
||||
o:depends({ [_n("reality")] = true })
|
||||
function o.custom_write(self, section, value)
|
||||
local new_t = {}
|
||||
if type(value) == "table" then
|
||||
new_t = api.table_remove_duplicates(value)
|
||||
else
|
||||
new_t = { value }
|
||||
end
|
||||
m:set(section, self.option:sub(1 + #option_prefix), new_t)
|
||||
end
|
||||
|
||||
o = s:option(ListValue, _n("alpn"), translate("alpn"))
|
||||
o.default = "default"
|
||||
|
||||
@@ -1014,7 +1014,6 @@ local default_file_tree = {
|
||||
}
|
||||
|
||||
local function get_api_json(url)
|
||||
local jsonc = require "luci.jsonc"
|
||||
local gh_proxy = uci_get_type("global_app", "github_proxy", "0")
|
||||
local return_code, content
|
||||
if gh_proxy == "1" then
|
||||
@@ -1345,6 +1344,25 @@ function set_default_cbi()
|
||||
self.template = appname .. "/cbi/tvalue"
|
||||
end
|
||||
end
|
||||
if true then
|
||||
--DynamicList
|
||||
local DynamicList = cbi.DynamicList
|
||||
function DynamicList.write(self, section, value)
|
||||
local new_t = {}
|
||||
if type(value) == "table" then
|
||||
new_t = table_remove_duplicates(value)
|
||||
else
|
||||
new_t = { value }
|
||||
end
|
||||
local new_val
|
||||
if self.cast == "string" then
|
||||
new_val = table.concat(new_t, " ")
|
||||
else
|
||||
new_val = new_t
|
||||
end
|
||||
return cbi.AbstractValue.write(self, section, new_val)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function return_map(map)
|
||||
@@ -1369,6 +1387,7 @@ function return_map(map)
|
||||
end
|
||||
|
||||
function luci_types(id, m, s, type_name, option_prefix)
|
||||
local cbi = require "luci.cbi"
|
||||
local fv_type
|
||||
local field_type = s.fields["type"]
|
||||
if field_type then
|
||||
@@ -1406,11 +1425,25 @@ function luci_types(id, m, s, type_name, option_prefix)
|
||||
if self.custom_write then
|
||||
self:custom_write(section, value)
|
||||
else
|
||||
local new_val = value
|
||||
if util.instanceof(self, cbi.DynamicList) then
|
||||
local new_t = {}
|
||||
if type(value) == "table" then
|
||||
new_t = table_remove_duplicates(value)
|
||||
else
|
||||
new_t = { value }
|
||||
end
|
||||
if self.cast == "string" then
|
||||
new_val = table.concat(new_t, " ")
|
||||
else
|
||||
new_val = new_t
|
||||
end
|
||||
end
|
||||
if self.rewrite_option then
|
||||
m:set(section, self.rewrite_option, value)
|
||||
m:set(section, self.rewrite_option, new_val)
|
||||
else
|
||||
if self.option:find(option_prefix) == 1 then
|
||||
m:set(section, self.option:sub(1 + #option_prefix), value)
|
||||
m:set(section, self.option:sub(1 + #option_prefix), new_val)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1283,6 +1283,9 @@ msgstr "使用全局配置"
|
||||
msgid "User-Agent"
|
||||
msgstr "用户代理(User-Agent)"
|
||||
|
||||
msgid "Used when the node link does not include this parameter."
|
||||
msgstr "当节点链接未包含该参数时,将使用此设置。"
|
||||
|
||||
msgid "Add"
|
||||
msgstr "添加"
|
||||
|
||||
|
||||
@@ -220,7 +220,7 @@ local function encode_vless(node)
|
||||
local link = "vless://" .. node.uuid .. "@" .. o.server .. ":" .. o.port
|
||||
local p = {}
|
||||
|
||||
if node.flow then table.insert(p, "flow=" .. urlencode(node.flow)) end
|
||||
if type(node.flow) == "string" and node.flow:sub(1, 5) == "xtls-" then table.insert(p, "flow=" .. urlencode(node.flow)) end
|
||||
if node.encryption then table.insert(p, "encryption=" .. urlencode(node.encryption)) end
|
||||
|
||||
-- TLS
|
||||
|
||||
@@ -29,6 +29,7 @@ local has_ssr = api.is_finded("ssr-local") and api.is_finded("ssr-redir")
|
||||
local has_singbox = api.finded_com("sing-box")
|
||||
local has_xray = api.finded_com("xray")
|
||||
local has_hysteria2 = api.finded_com("hysteria")
|
||||
local DEFAULT_ALLOWINSECURE = true
|
||||
local DEFAULT_FILTER_KEYWORD_MODE = uci:get(appname, "@global_subscribe[0]", "filter_keyword_mode") or "0"
|
||||
local DEFAULT_FILTER_KEYWORD_DISCARD_LIST = uci:get(appname, "@global_subscribe[0]", "filter_discard_list") or {}
|
||||
local DEFAULT_FILTER_KEYWORD_KEEP_LIST = uci:get(appname, "@global_subscribe[0]", "filter_keep_list") or {}
|
||||
@@ -516,6 +517,7 @@ end
|
||||
-- 处理数据
|
||||
local function processData(szType, content, add_mode, group, sub_cfg)
|
||||
--log(2, content, add_mode, group)
|
||||
local sub_allowinsecure = DEFAULT_ALLOWINSECURE
|
||||
local sub_ss_type = DEFAULT_SS_TYPE
|
||||
local sub_trojan_type = DEFAULT_TROJAN_TYPE
|
||||
local sub_vmess_type = DEFAULT_VMESS_TYPE
|
||||
@@ -523,6 +525,9 @@ local function processData(szType, content, add_mode, group, sub_cfg)
|
||||
local sub_hysteria2_type = DEFAULT_HYSTERIA2_TYPE
|
||||
local sub_hy_up_mbps, sub_hy_down_mbps = 1000, 1000
|
||||
if sub_cfg then
|
||||
if sub_cfg.allowInsecure and sub_cfg.allowInsecure ~= "1" then
|
||||
sub_allowinsecure = nil
|
||||
end
|
||||
local ss_type = sub_cfg.ss_type or "global"
|
||||
if ss_type ~= "global" and core_has[ss_type] then
|
||||
sub_ss_type = ss_type
|
||||
@@ -695,7 +700,8 @@ local function processData(szType, content, add_mode, group, sub_cfg)
|
||||
result.tls_serverName = (info.sni and info.sni ~= "") and info.sni or info.host
|
||||
result.tls_pinSHA256 = info.pcs
|
||||
result.tls_CertByName = info.vcn
|
||||
result.tls_allowInsecure = info.allowinsecure or info.allowInsecure or info.insecure
|
||||
local insecure = info.allowinsecure or info.allowInsecure or info.insecure
|
||||
result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0")
|
||||
else
|
||||
result.tls = "0"
|
||||
end
|
||||
@@ -971,7 +977,8 @@ local function processData(szType, content, add_mode, group, sub_cfg)
|
||||
result.reality_mldsa65Verify = params.pqv or nil
|
||||
end
|
||||
end
|
||||
result.tls_allowInsecure = params.allowinsecure or params.allowInsecure or params.insecure
|
||||
local insecure = params.allowinsecure or params.allowInsecure or params.insecure
|
||||
result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0")
|
||||
result.uot = params.udp
|
||||
else
|
||||
result.error_msg = "请更换 Xray 或 Sing-Box 来支持 SS 更多的传输方式。"
|
||||
@@ -1089,7 +1096,8 @@ local function processData(szType, content, add_mode, group, sub_cfg)
|
||||
end
|
||||
result.tls_pinSHA256 = params.pcs
|
||||
result.tls_CertByName = params.vcn
|
||||
result.tls_allowInsecure = params.allowinsecure or params.allowInsecure or params.insecure
|
||||
local insecure = params.allowinsecure or params.allowInsecure or params.insecure
|
||||
result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0")
|
||||
end
|
||||
|
||||
if not params.type then params.type = "tcp" end
|
||||
@@ -1344,7 +1352,8 @@ local function processData(szType, content, add_mode, group, sub_cfg)
|
||||
result.use_mldsa65Verify = (params.pqv and params.pqv ~= "") and "1" or nil
|
||||
result.reality_mldsa65Verify = params.pqv or nil
|
||||
end
|
||||
result.tls_allowInsecure = params.allowinsecure or params.allowInsecure or params.insecure
|
||||
local insecure = params.allowinsecure or params.allowInsecure or params.insecure
|
||||
result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0")
|
||||
end
|
||||
|
||||
result.port = port
|
||||
@@ -1400,7 +1409,8 @@ local function processData(szType, content, add_mode, group, sub_cfg)
|
||||
result.hysteria_auth_type = "string"
|
||||
result.hysteria_auth_password = params.auth
|
||||
result.tls_serverName = params.peer or params.sni or ""
|
||||
result.tls_allowInsecure = params.allowinsecure or params.allowInsecure or params.insecure
|
||||
local insecure = params.allowinsecure or params.allowInsecure or params.insecure
|
||||
result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0")
|
||||
result.alpn = params.alpn
|
||||
result.hysteria_up_mbps = params.upmbps or sub_hy_up_mbps
|
||||
result.hysteria_down_mbps = params.downmbps or sub_hy_down_mbps
|
||||
@@ -1445,7 +1455,8 @@ local function processData(szType, content, add_mode, group, sub_cfg)
|
||||
result.tls_serverName = params.sni
|
||||
result.tls_pinSHA256 = params.pcs or params.pinsha256
|
||||
result.tls_CertByName = params.vcn
|
||||
result.tls_allowInsecure = params.allowinsecure or params.insecure
|
||||
local insecure = params.allowinsecure or params.insecure
|
||||
result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0")
|
||||
result.hysteria2_up_mbps = params.upmbps or (sub_cfg and sub_hy_up_mbps or nil)
|
||||
result.hysteria2_down_mbps = params.downmbps or (sub_cfg and sub_hy_down_mbps or nil)
|
||||
result.hysteria2_hop = params.mport
|
||||
@@ -1526,7 +1537,8 @@ local function processData(szType, content, add_mode, group, sub_cfg)
|
||||
result.tuic_alpn = params.alpn or "h3"
|
||||
result.tuic_congestion_control = params.congestion_control or "cubic"
|
||||
result.tuic_udp_relay_mode = params.udp_relay_mode or "native"
|
||||
result.tls_allowInsecure = params.allowinsecure or params.insecure or params.allow_insecure
|
||||
local insecure = params.allowinsecure or params.insecure or params.allow_insecure
|
||||
result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0")
|
||||
elseif szType == "anytls" then
|
||||
if has_singbox then
|
||||
result.type = 'sing-box'
|
||||
@@ -1593,7 +1605,8 @@ local function processData(szType, content, add_mode, group, sub_cfg)
|
||||
end
|
||||
end
|
||||
result.port = port
|
||||
result.tls_allowInsecure = params.allowinsecure or params.insecure
|
||||
local insecure = params.allowinsecure or params.insecure
|
||||
result.tls_allowInsecure = (insecure == "1" or insecure == "0") and insecure or (sub_allowinsecure and "1" or "0")
|
||||
end
|
||||
elseif szType == 'naive+https' or szType == 'naive+quic' then
|
||||
if has_singbox then
|
||||
|
||||
@@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-passwall2
|
||||
PKG_VERSION:=26.8.7
|
||||
PKG_RELEASE:=75
|
||||
PKG_RELEASE:=76
|
||||
PKG_PO_VERSION:=$(PKG_VERSION)
|
||||
|
||||
PKG_CONFIG_DEPENDS:= \
|
||||
|
||||
@@ -171,19 +171,6 @@ node_socks_bind_local:depends({ node = "", ["!reverse"] = true })
|
||||
|
||||
s:tab("DNS", translate("DNS"))
|
||||
|
||||
o = s:taboption("DNS", TextValue, "direct_dns_shunt", translate("Direct domain DNS routing"))
|
||||
o.description = "<br /><ul>"
|
||||
.. "<li>" .. translate("Subdomain (recommended): Begining with 'domain:' and the rest is a domain. When the targeting domain is exactly the value, or is a subdomain of the value, this rule takes effect. Example: rule 'domain:v2ray.com' matches 'www.v2ray.com', 'v2ray.com', but not 'xv2ray.com'.") .. "</li>"
|
||||
.. "<li>" .. translate("Full domain: Begining with 'full:' and the rest is a domain. When the targeting domain is exactly the value, the rule takes effect. Example: rule 'domain:v2ray.com' matches 'v2ray.com', but not 'www.v2ray.com'.") .. "</li>"
|
||||
.. "<li>" .. translate("Such as:") .. "</li>"
|
||||
.. "<li>" .. "domain:my-nodes.com tcp://223.5.5.5" .. "</li>"
|
||||
.. "<li>" .. "domain:vpn.com udp://119.29.29.29:53" .. "</li>"
|
||||
.. "<li>" .. "full:www.dnspod.com https://120.53.53.53/dns-query" .. "</li>"
|
||||
.. "<li>" .. '<a style="color:red">' .. translate("Please note that the program will not start if the format is incorrect!") .. '</a>' .. "</li>"
|
||||
.. "</ul>"
|
||||
o.rows = 3
|
||||
o.wrap = "off"
|
||||
|
||||
o = s:taboption("DNS", ListValue, "direct_dns_query_strategy", translate("Direct Query Strategy"))
|
||||
o.default = "UseIP"
|
||||
o:value("UseIP")
|
||||
|
||||
@@ -5,7 +5,6 @@ nixio = require "nixio"
|
||||
fs = require "nixio.fs"
|
||||
sys = require "luci.sys"
|
||||
uci = require"luci.model.uci".cursor()
|
||||
cbi = require "luci.cbi"
|
||||
util = require "luci.util"
|
||||
datatypes = require "luci.cbi.datatypes"
|
||||
jsonc = require "luci.jsonc"
|
||||
@@ -1014,7 +1013,6 @@ local default_file_tree = {
|
||||
}
|
||||
|
||||
function get_api_json(url)
|
||||
local jsonc = require "luci.jsonc"
|
||||
local return_code, content = curl_logic(url, nil, curl_args)
|
||||
if return_code ~= 0 or content == "" then return {} end
|
||||
return jsonc.parse(content) or {}
|
||||
@@ -1387,6 +1385,7 @@ function set_apply_on_parse(map)
|
||||
end
|
||||
|
||||
function set_default_cbi()
|
||||
local cbi = require "luci.cbi"
|
||||
if true then
|
||||
--TextValue
|
||||
local TextValue = cbi.TextValue
|
||||
@@ -1418,6 +1417,7 @@ function set_default_cbi()
|
||||
end
|
||||
|
||||
function return_map(map)
|
||||
local cbi = require "luci.cbi"
|
||||
local api = require "luci.passwall2.api"
|
||||
if true then
|
||||
-- header
|
||||
@@ -1438,6 +1438,7 @@ function return_map(map)
|
||||
end
|
||||
|
||||
function luci_types(id, m, s, type_name, option_prefix)
|
||||
local cbi = require "luci.cbi"
|
||||
local fv_type
|
||||
local field_type = s.fields["type"]
|
||||
if field_type then
|
||||
|
||||
@@ -111,34 +111,6 @@ for i, v in ipairs(cipherSuites) do
|
||||
end
|
||||
]]--
|
||||
|
||||
function parseDNS(str)
|
||||
local result_dns_server
|
||||
-- [proto]://[ip]
|
||||
-- [proto]://[ip]:[port]
|
||||
-- https://[ip]/[path]
|
||||
-- https://[ip]:[port]/[path]
|
||||
local _a = api.parseURL(str)
|
||||
if _a then
|
||||
if _a.protocol == "tcp" or _a.protocol == "udp" or _a.protocol == "https" then
|
||||
result_dns_server = {
|
||||
type = _a.protocol,
|
||||
server = _a.hostname
|
||||
}
|
||||
if _a.port then
|
||||
result_dns_server.server_port = _a.port
|
||||
else
|
||||
if _a.protocol == "https" then
|
||||
result_dns_server.server_port = 443
|
||||
else
|
||||
result_dns_server.server_port = 53
|
||||
end
|
||||
end
|
||||
result_dns_server.path = _a.pathname
|
||||
end
|
||||
end
|
||||
return result_dns_server
|
||||
end
|
||||
|
||||
function gen_outbound(flag, node, tag, proxy_table)
|
||||
local result = nil
|
||||
if node then
|
||||
@@ -2023,6 +1995,7 @@ function gen_config(var)
|
||||
else default_dns_flag = "direct"
|
||||
end
|
||||
dns.final = default_dns_flag
|
||||
dns.strategy = default_dns_flag == "remote" and remote_strategy or direct_strategy
|
||||
|
||||
-- DNS in order of shunt
|
||||
if dns_domain_rules and #dns_domain_rules > 0 then
|
||||
@@ -2046,12 +2019,43 @@ function gen_config(var)
|
||||
dns_rule.server = nil
|
||||
end
|
||||
if value.outboundTag == "direct" then
|
||||
dns_rule.strategy = direct_strategy
|
||||
local block_rule
|
||||
if direct_strategy == "ipv4_only" then
|
||||
block_rule = api.clone(dns_rule)
|
||||
block_rule.query_type = { "AAAA" }
|
||||
elseif direct_strategy == "ipv6_only" then
|
||||
block_rule = api.clone(dns_rule)
|
||||
block_rule.query_type = { "A" }
|
||||
end
|
||||
if block_rule then
|
||||
block_rule.action = "predefined"
|
||||
block_rule.rcode = "NOERROR"
|
||||
block_rule.disable_cache = nil
|
||||
block_rule.server = nil
|
||||
table.insert(dns.rules, block_rule)
|
||||
end
|
||||
end
|
||||
if value.outboundTag ~= "block" and value.outboundTag ~= "direct" then
|
||||
dns_rule.server = "remote"
|
||||
dns_rule.rewrite_ttl = 30
|
||||
dns_rule.strategy = remote_strategy
|
||||
if true then
|
||||
local block_rule
|
||||
if remote_strategy == "ipv4_only" then
|
||||
block_rule = api.clone(dns_rule)
|
||||
block_rule.query_type = { "AAAA" }
|
||||
elseif remote_strategy == "ipv6_only" then
|
||||
block_rule = api.clone(dns_rule)
|
||||
block_rule.query_type = { "A" }
|
||||
end
|
||||
if block_rule then
|
||||
block_rule.action = "predefined"
|
||||
block_rule.rcode = "NOERROR"
|
||||
block_rule.disable_cache = nil
|
||||
block_rule.server = nil
|
||||
block_rule.rewrite_ttl = nil
|
||||
table.insert(dns.rules, block_rule)
|
||||
end
|
||||
end
|
||||
dns_rule.client_subnet = remote_dns_client_ip
|
||||
if value.outboundTag ~= COMMON.default_outbound_tag and remote_server.server and remote_dns_detour ~= "direct" then
|
||||
local remote_dns_server = api.clone(remote_server)
|
||||
@@ -2062,9 +2066,13 @@ function gen_config(var)
|
||||
end
|
||||
if value.fakedns then
|
||||
local fakedns_dns_rule = api.clone(dns_rule)
|
||||
fakedns_dns_rule.query_type = {
|
||||
"A", "AAAA"
|
||||
}
|
||||
if remote_strategy == "ipv4_only" then
|
||||
fakedns_dns_rule.query_type = { "A" }
|
||||
elseif remote_strategy == "ipv6_only" then
|
||||
fakedns_dns_rule.query_type = { "AAAA" }
|
||||
else
|
||||
fakedns_dns_rule.query_type = { "A", "AAAA" }
|
||||
end
|
||||
fakedns_dns_rule.server = fakedns_tag
|
||||
fakedns_dns_rule.disable_cache = true
|
||||
fakedns_dns_rule.client_subnet = nil
|
||||
@@ -2076,23 +2084,26 @@ function gen_config(var)
|
||||
end
|
||||
end
|
||||
if default_dns_flag == "remote" then
|
||||
local dns_rule_query_type = { "A", "AAAA" }
|
||||
if remote_strategy == "ipv4_only" then
|
||||
dns_rule_query_type = { "A" }
|
||||
elseif remote_strategy == "ipv6_only" then
|
||||
dns_rule_query_type = { "AAAA" }
|
||||
end
|
||||
if remote_dns_fake then
|
||||
-- When default is not direct and enable fakedns, default DNS use FakeDNS.
|
||||
local fakedns_dns_rule = {
|
||||
query_type = {
|
||||
"A", "AAAA"
|
||||
},
|
||||
query_type = dns_rule_query_type,
|
||||
server = fakedns_tag,
|
||||
disable_cache = true,
|
||||
rewrite_ttl = 30,
|
||||
strategy = remote_strategy,
|
||||
rewrite_ttl = 30
|
||||
}
|
||||
table.insert(dns.rules, fakedns_dns_rule)
|
||||
else
|
||||
local remote_dns_rule = {
|
||||
query_type = dns_rule_query_type,
|
||||
server = "remote",
|
||||
disable_cache = true,
|
||||
strategy = remote_strategy,
|
||||
}
|
||||
table.insert(dns.rules, remote_dns_rule)
|
||||
end
|
||||
@@ -2328,156 +2339,7 @@ function gen_proto_config(var)
|
||||
return jsonc.stringify(config, 1)
|
||||
end
|
||||
|
||||
function gen_front_dns_config(var)
|
||||
local dns_listen_port = var["dns_listen_port"]
|
||||
local direct_dns_udp_server = var["direct_dns_udp_server"]
|
||||
local direct_dns_udp_port = var["direct_dns_udp_port"]
|
||||
local direct_dns_query_strategy = var["direct_dns_query_strategy"]
|
||||
local default_dns_udp_server = var["default_dns_udp_server"]
|
||||
local default_dns_udp_port = var["default_dns_udp_port"]
|
||||
|
||||
local dns = {
|
||||
servers = {},
|
||||
rules = {}
|
||||
}
|
||||
local inbounds = {}
|
||||
local outbounds = {}
|
||||
local route = {}
|
||||
|
||||
local direct_strategy = "prefer_ipv6"
|
||||
if direct_dns_query_strategy == "UseIPv4" then
|
||||
direct_strategy = "ipv4_only"
|
||||
elseif direct_dns_query_strategy == "UseIPv6" then
|
||||
direct_strategy = "ipv6_only"
|
||||
end
|
||||
|
||||
table.insert(outbounds, {
|
||||
type = "direct",
|
||||
tag = "direct",
|
||||
routing_mark = 255,
|
||||
})
|
||||
|
||||
local direct_dns_shunt = uci:get(appname, "@global[0]", "direct_dns_shunt") or ""
|
||||
if #direct_dns_shunt > 0 then
|
||||
local dns_server = {}
|
||||
string.gsub(direct_dns_shunt, '[^' .. "\r\n" .. ']+', function(w)
|
||||
if w:find("#") == 1 then return end
|
||||
local domain = sys.exec(string.format("echo -n $(echo %s | awk -F ' ' '{print $1}')", w))
|
||||
local dns = sys.exec(string.format("echo -n $(echo %s | awk -F ' ' '{print $2}')", w))
|
||||
if domain ~= "" and dns ~= "" then
|
||||
local new_dns_server = parseDNS(dns)
|
||||
if new_dns_server then
|
||||
if not dns_server[dns] then
|
||||
dns_server[dns] = {}
|
||||
end
|
||||
if not dns_server[dns].server then
|
||||
dns_server[dns].server = new_dns_server
|
||||
dns_server[dns].server.tag = dns
|
||||
dns_server[dns].server.detour = "direct"
|
||||
end
|
||||
if not dns_server[dns].rule then
|
||||
dns_server[dns].rule = {
|
||||
action = "route",
|
||||
server = dns,
|
||||
domain = {},
|
||||
domain_suffix = {},
|
||||
domain_keyword = {}
|
||||
}
|
||||
end
|
||||
if domain:find("full:") == 1 then
|
||||
table.insert(dns_server[dns].rule.domain, domain:sub(1 + #"full:"))
|
||||
elseif domain:find("domain:") == 1 then
|
||||
table.insert(dns_server[dns].rule.domain_suffix, domain:sub(1 + #"domain:"))
|
||||
else
|
||||
table.insert(dns_server[dns].rule.domain_keyword, domain)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
for k, v in pairs(dns_server) do
|
||||
table.insert(dns.servers, v.server)
|
||||
if #v.rule.domain == 0 then v.rule.domain = nil end
|
||||
if #v.rule.domain_suffix == 0 then v.rule.domain_suffix = nil end
|
||||
if #v.rule.domain_keyword == 0 then v.rule.domain_keyword = nil end
|
||||
table.insert(dns.rules, v.rule)
|
||||
end
|
||||
end
|
||||
|
||||
if direct_dns_udp_server then
|
||||
table.insert(dns.servers, {
|
||||
tag = "direct",
|
||||
type = "udp",
|
||||
server = direct_dns_udp_server,
|
||||
server_port = tonumber(direct_dns_udp_port) or 53,
|
||||
detour = "direct"
|
||||
})
|
||||
local node_domain = {}
|
||||
local nodes_domain_text = sys.exec('uci show passwall2 | grep ".address=" | cut -d "\'" -f 2 | grep "[a-zA-Z]$" | sort -u')
|
||||
string.gsub(nodes_domain_text, '[^' .. "\r\n" .. ']+', function(w)
|
||||
w = (w or ""):lower()
|
||||
table.insert(node_domain, w)
|
||||
end)
|
||||
if #node_domain > 0 then
|
||||
table.insert(dns.rules, {
|
||||
action = "route",
|
||||
server = "direct",
|
||||
domain = node_domain
|
||||
})
|
||||
end
|
||||
route.default_domain_resolver = {
|
||||
server = "direct",
|
||||
strategy = direct_strategy
|
||||
}
|
||||
end
|
||||
|
||||
if default_dns_udp_server then
|
||||
table.insert(dns.servers, {
|
||||
tag = "default",
|
||||
type = "udp",
|
||||
server = default_dns_udp_server,
|
||||
server_port = tonumber(default_dns_udp_port) or 53,
|
||||
detour = "direct"
|
||||
})
|
||||
dns.final = "default"
|
||||
else
|
||||
dns.final = "direct"
|
||||
end
|
||||
|
||||
local dns_in_inbound = {
|
||||
type = "direct",
|
||||
tag = "dns-in",
|
||||
listen = "127.0.0.1",
|
||||
listen_port = tonumber(dns_listen_port),
|
||||
}
|
||||
table.insert(inbounds, dns_in_inbound)
|
||||
|
||||
route.rules = {}
|
||||
table.insert(route.rules, {
|
||||
action = "hijack-dns",
|
||||
inbound = dns_in_inbound.tag
|
||||
})
|
||||
table.insert(route.rules, {
|
||||
action = "sniff",
|
||||
inbound = dns_in_inbound.tag
|
||||
})
|
||||
route.final = "direct"
|
||||
|
||||
local config = {
|
||||
log = {
|
||||
disabled = true,
|
||||
level = "debug",
|
||||
timestamp = true,
|
||||
},
|
||||
dns = dns,
|
||||
inbounds = inbounds,
|
||||
outbounds = outbounds,
|
||||
route = route
|
||||
}
|
||||
return jsonc.stringify(config, 1)
|
||||
end
|
||||
|
||||
_G.gen_config = gen_config
|
||||
_G.gen_front_dns_config = gen_front_dns_config
|
||||
_G.gen_proto_config = gen_proto_config
|
||||
_G.geo_convert_srs = geo_convert_srs
|
||||
|
||||
|
||||
@@ -51,35 +51,6 @@ for i, v in ipairs(cipherSuites) do
|
||||
end
|
||||
]]--
|
||||
|
||||
function parseDNS(str)
|
||||
local result_dns_server
|
||||
-- [proto]://[ip]
|
||||
-- [proto]://[ip]:[port]
|
||||
-- https://[ip]/[path]
|
||||
-- https://[ip]:[port]/[path]
|
||||
local _a = api.parseURL(str)
|
||||
if _a then
|
||||
if _a.protocol == "tcp" or _a.protocol == "udp" or _a.protocol == "https" then
|
||||
result_dns_server = {
|
||||
address = str
|
||||
}
|
||||
if _a.protocol == "udp" then
|
||||
result_dns_server.address = _a.hostname
|
||||
end
|
||||
if _a.port then
|
||||
result_dns_server.port = _a.port
|
||||
else
|
||||
if _a.protocol == "https" then
|
||||
result_dns_server.port = 443
|
||||
else
|
||||
result_dns_server.port = 53
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return result_dns_server
|
||||
end
|
||||
|
||||
function gen_outbound(flag, node, tag, proxy_table)
|
||||
local result = nil
|
||||
if node then
|
||||
@@ -2186,157 +2157,7 @@ function gen_proto_config(var)
|
||||
return jsonc.stringify(config, 1)
|
||||
end
|
||||
|
||||
function gen_front_dns_config(var)
|
||||
local dns_listen_port = var["dns_listen_port"]
|
||||
local direct_dns_udp_server = var["direct_dns_udp_server"]
|
||||
local direct_dns_udp_port = var["direct_dns_udp_port"]
|
||||
local default_dns_udp_server = var["default_dns_udp_server"]
|
||||
local default_dns_udp_port = var["default_dns_udp_port"]
|
||||
|
||||
local queryStrategy = "UseIP"
|
||||
local dns = {
|
||||
tag = "dns-global-direct",
|
||||
disableCache = false,
|
||||
disableFallback = true,
|
||||
disableFallbackIfMatch = true,
|
||||
queryStrategy = queryStrategy,
|
||||
servers = {}
|
||||
}
|
||||
local inbounds = {}
|
||||
local outbounds = {}
|
||||
local routing = {
|
||||
rules = {}
|
||||
}
|
||||
|
||||
table.insert(outbounds, {
|
||||
tag = "direct",
|
||||
protocol = "freedom",
|
||||
settings = {
|
||||
domainStrategy = queryStrategy
|
||||
},
|
||||
streamSettings = {
|
||||
sockopt = {
|
||||
mark = 255
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
if default_dns_udp_server then
|
||||
table.insert(dns.servers, {
|
||||
tag = "default",
|
||||
address = default_dns_udp_server,
|
||||
port = tonumber(default_dns_udp_port) or 53,
|
||||
queryStrategy = queryStrategy,
|
||||
})
|
||||
end
|
||||
|
||||
local direct_dns_shunt = uci:get(appname, "@global[0]", "direct_dns_shunt") or ""
|
||||
if #direct_dns_shunt > 0 then
|
||||
local dns_server = {}
|
||||
string.gsub(direct_dns_shunt, '[^' .. "\r\n" .. ']+', function(w)
|
||||
if w:find("#") == 1 then return end
|
||||
local domain = sys.exec(string.format("echo -n $(echo %s | awk -F ' ' '{print $1}')", w))
|
||||
local dns = sys.exec(string.format("echo -n $(echo %s | awk -F ' ' '{print $2}')", w))
|
||||
if domain ~= "" and dns ~= "" then
|
||||
local new_dns_server = parseDNS(dns)
|
||||
if new_dns_server then
|
||||
if not dns_server[dns] then
|
||||
dns_server[dns] = {}
|
||||
end
|
||||
dns_server[dns].tag = dns
|
||||
dns_server[dns].queryStrategy = queryStrategy
|
||||
dns_server[dns].address = new_dns_server.address
|
||||
dns_server[dns].port = new_dns_server.port
|
||||
dns_server[dns].finalQuery = true
|
||||
if not dns_server[dns].domains then
|
||||
dns_server[dns].domains = {}
|
||||
end
|
||||
table.insert(dns_server[dns].domains, domain)
|
||||
end
|
||||
end
|
||||
end)
|
||||
for k, v in pairs(dns_server) do
|
||||
table.insert(dns.servers, v)
|
||||
table.insert(routing.rules, {
|
||||
inboundTag = {
|
||||
v.tag
|
||||
},
|
||||
outboundTag = "direct"
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
if direct_dns_udp_server then
|
||||
local node_domain = {}
|
||||
local nodes_domain_text = sys.exec('uci show passwall2 | grep ".address=" | cut -d "\'" -f 2 | grep "[a-zA-Z]$" | sort -u')
|
||||
string.gsub(nodes_domain_text, '[^' .. "\r\n" .. ']+', function(w)
|
||||
w = (w or ""):lower()
|
||||
table.insert(node_domain, "full:" .. w)
|
||||
end)
|
||||
if #node_domain > 0 then
|
||||
table.insert(dns.servers, {
|
||||
tag = "dns-in-vpslist",
|
||||
address = direct_dns_udp_server,
|
||||
port = tonumber(direct_dns_udp_port) or 53,
|
||||
queryStrategy = queryStrategy,
|
||||
domains = node_domain,
|
||||
finalQuery = true,
|
||||
disableCache = false,
|
||||
serveStale = true,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
table.insert(inbounds, {
|
||||
tag = "dns-in",
|
||||
listen = "127.0.0.1",
|
||||
port = tonumber(dns_listen_port),
|
||||
protocol = "dokodemo-door",
|
||||
settings = {
|
||||
address = "0.0.0.0",
|
||||
network = "tcp,udp"
|
||||
}
|
||||
})
|
||||
|
||||
table.insert(outbounds, {
|
||||
tag = "dns-out",
|
||||
protocol = "dns",
|
||||
proxySettings = {
|
||||
tag = "direct"
|
||||
},
|
||||
settings = {
|
||||
address = direct_dns_udp_server,
|
||||
port = tonumber(direct_dns_udp_port) or 53,
|
||||
network = "udp",
|
||||
nonIPQuery = "skip",
|
||||
blockTypes = {
|
||||
65
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
table.insert(routing.rules, {
|
||||
inboundTag = {
|
||||
"dns-in"
|
||||
},
|
||||
outboundTag = "dns-out"
|
||||
})
|
||||
|
||||
local config = {
|
||||
log = {
|
||||
dnsLog = true,
|
||||
loglevel = "debug"
|
||||
},
|
||||
dns = dns,
|
||||
inbounds = inbounds,
|
||||
outbounds = outbounds,
|
||||
routing = routing
|
||||
}
|
||||
return jsonc.stringify(config, 1)
|
||||
end
|
||||
|
||||
_G.gen_config = gen_config
|
||||
_G.gen_front_dns_config = gen_front_dns_config
|
||||
_G.gen_proto_config = gen_proto_config
|
||||
|
||||
if arg[1] then
|
||||
|
||||
@@ -121,12 +121,6 @@ msgstr "0 به معنای عدم استفاده است"
|
||||
msgid "Current node: %s"
|
||||
msgstr "گره فعلی: %s"
|
||||
|
||||
msgid "Direct domain DNS routing"
|
||||
msgstr "مسیریابی مستقیم DNS دامنه"
|
||||
|
||||
msgid "Please note that the program will not start if the format is incorrect!"
|
||||
msgstr "لطفا توجه داشته باشید که اگر قالب نادرست باشد، برنامه شروع نخواهد شد!"
|
||||
|
||||
msgid "IP:Port mode acceptable, multi value split with english comma."
|
||||
msgstr "حالت IP:Port قابل قبول است، مقادیر متعدد را با کاما انگلیسی جدا کنید."
|
||||
|
||||
|
||||
@@ -118,12 +118,6 @@ msgstr "0 — отключить функцию"
|
||||
msgid "Current node: %s"
|
||||
msgstr "Текущий узел: %s"
|
||||
|
||||
msgid "Direct domain DNS routing"
|
||||
msgstr "Прямая маршрутизация DNS домена"
|
||||
|
||||
msgid "Please note that the program will not start if the format is incorrect!"
|
||||
msgstr "Обратите внимание, что программа не запустится, если формат указан неверно!"
|
||||
|
||||
msgid "IP:Port mode acceptable, multi value split with english comma."
|
||||
msgstr "Допустим формат IP:Port. Несколько значений указывайте через запятую."
|
||||
|
||||
|
||||
@@ -118,12 +118,6 @@ msgstr "0为不使用"
|
||||
msgid "Current node: %s"
|
||||
msgstr "当前节点:%s"
|
||||
|
||||
msgid "Direct domain DNS routing"
|
||||
msgstr "直连域名 DNS 分流"
|
||||
|
||||
msgid "Please note that the program will not start if the format is incorrect!"
|
||||
msgstr "请注意,格式不正确将无法启动!"
|
||||
|
||||
msgid "IP:Port mode acceptable, multi value split with english comma."
|
||||
msgstr "接受 IP:Port 形式的输入,多个以英文逗号分隔。"
|
||||
|
||||
|
||||
@@ -118,12 +118,6 @@ msgstr "0為不使用"
|
||||
msgid "Current node: %s"
|
||||
msgstr "當前節點:%s"
|
||||
|
||||
msgid "Direct domain DNS routing"
|
||||
msgstr "直連網域 DNS 分流"
|
||||
|
||||
msgid "Please note that the program will not start if the format is incorrect!"
|
||||
msgstr "請注意,格式不正確將無法啟動!"
|
||||
|
||||
msgid "IP:Port mode acceptable, multi value split with english comma."
|
||||
msgstr "接受 IP:Port 形式的輸入,多個以英文逗号分隔。"
|
||||
|
||||
|
||||
@@ -655,58 +655,13 @@ run_global() {
|
||||
set_cache_var "ACL_GLOBAL_redir_port" "$REDIR_PORT"
|
||||
}
|
||||
|
||||
run_front_dns() {
|
||||
local switch=0
|
||||
direct_dns_shunt=$(config_t_get global direct_dns_shunt)
|
||||
direct_dns_shunt=$(echo "${direct_dns_shunt}" | grep -v "^#")
|
||||
[ -n "${direct_dns_shunt}" ] && switch=1
|
||||
[ "${switch}" == "1" ] && {
|
||||
local config_file="${TMP_PATH}/direct_dns.json"
|
||||
local log_file="${TMP_PATH}/direct_dns.log"
|
||||
log_file="/dev/null"
|
||||
local listen_port=$(get_new_port 10553)
|
||||
json_init
|
||||
json_add_string "dns_listen_port" "${listen_port}"
|
||||
json_add_string "direct_dns_udp_server" "${DIRECT_DNS_UDP_SERVER}"
|
||||
json_add_string "direct_dns_udp_port" "${DIRECT_DNS_UDP_PORT}"
|
||||
json_add_string "direct_dns_query_strategy" "${DIRECT_DNS_QUERY_STRATEGY}"
|
||||
[ -n "${ACL_GLOBAL_node}" ] && [ -n "${TUN_DNS_PORT}" ] && {
|
||||
json_add_string "default_dns_udp_server" "127.0.0.1"
|
||||
json_add_string "default_dns_udp_port" "${TUN_DNS_PORT}"
|
||||
}
|
||||
local _json_arg="$(json_dump)"
|
||||
|
||||
local prefer_core=""
|
||||
[ -n "${XRAY_BIN}" ] && prefer_core="xray"
|
||||
[ -n "${SINGBOX_BIN}" ] && prefer_core="sing-box"
|
||||
|
||||
if [ "${prefer_core}" = "xray" ]; then
|
||||
lua $UTIL_XRAY gen_front_dns_config "${_json_arg}" > $config_file
|
||||
ln_run 0 "$XRAY_BIN" "xray" "${log_file}" run -c "$config_file"
|
||||
elif [ "${prefer_core}" = "sing-box" ]; then
|
||||
lua $UTIL_SINGBOX gen_front_dns_config "${_json_arg}" > $config_file
|
||||
ln_run 0 "$SINGBOX_BIN" "sing-box" "${log_file}" run -c "$config_file"
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
|
||||
FRONT_DNS_SERVER="127.0.0.1"
|
||||
FRONT_DNS_PORT="${listen_port}"
|
||||
}
|
||||
}
|
||||
|
||||
run_global_dnsmasq() {
|
||||
[ -z "${ACL_GLOBAL_node}" ] && [ -z "${FRONT_DNS_PORT}" ] && return
|
||||
[ -z "${ACL_GLOBAL_node}" ] && return
|
||||
local RUN_NEW_DNSMASQ=1
|
||||
RUN_NEW_DNSMASQ=${DNS_REDIRECT}
|
||||
DNSMASQ_DEFAULT_DNS="${AUTO_DNS}"
|
||||
DNSMASQ_LOCAL_DNS="${LOCAL_DNS:-${AUTO_DNS}}"
|
||||
DNSMASQ_TUN_DNS="${TUN_DNS}"
|
||||
[ -n "${FRONT_DNS_PORT}" ] && {
|
||||
DNSMASQ_DEFAULT_DNS="${FRONT_DNS_SERVER}#${FRONT_DNS_PORT}"
|
||||
DNSMASQ_LOCAL_DNS="${DNSMASQ_DEFAULT_DNS}"
|
||||
DNSMASQ_TUN_DNS="${DNSMASQ_DEFAULT_DNS}"
|
||||
}
|
||||
if [ "${RUN_NEW_DNSMASQ}" == "0" ]; then
|
||||
#The old logic will be removed in the future.
|
||||
#Run a copy dnsmasq instance, DNS hijack that don't need a proxy devices.
|
||||
@@ -1194,7 +1149,6 @@ start() {
|
||||
fi
|
||||
mkdir -p ${GLOBAL_ACL_PATH}
|
||||
[ "$ENABLED_DEFAULT_ACL" == 1 ] && run_global
|
||||
run_front_dns
|
||||
run_global_dnsmasq
|
||||
[ -n "$USE_TABLES" ] && source $APP_PATH/${USE_TABLES}.sh start
|
||||
set_cache_var "USE_TABLES" "$USE_TABLES"
|
||||
|
||||
@@ -17,7 +17,7 @@ LUCI_NAME:=luci-theme-footstrap
|
||||
FOOTSTRAP_VERSION?=
|
||||
ifneq ($(FOOTSTRAP_VERSION),)
|
||||
PKG_VERSION:=$(FOOTSTRAP_VERSION)
|
||||
PKG_RELEASE:=9
|
||||
PKG_RELEASE:=10
|
||||
endif
|
||||
|
||||
LUCI_TITLE:=Footstrap Theme
|
||||
|
||||
@@ -381,6 +381,22 @@ function seed() {
|
||||
adoptEntry();
|
||||
}
|
||||
|
||||
/* Does this document already carry the stylesheet a menu.d node names?
|
||||
*
|
||||
* The value is a path under /luci-static/resources (`view/foo/foo.css`), and head.ut prints it with
|
||||
* a `?v=` cache key, so compare the PATH only and by suffix — the theme does not get to assume the
|
||||
* resource base, and a re-hosted sheet keeps its element and its href (fs-sheets.js disables the
|
||||
* <link>, it never removes it), which is exactly the "already here" this asks about. */
|
||||
function documentHasSheet(css) {
|
||||
const want = '/' + css.replace(/^\/+/, '');
|
||||
for (const link of document.querySelectorAll('link[rel~="stylesheet"][href]')) {
|
||||
const href = (link.getAttribute('href') || '').split('?')[0];
|
||||
if (href.endsWith(want))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Attempt an in-place navigation to `pathname`. Returns true if handled as a
|
||||
* SPA nav (caller should preventDefault), false to let the browser do a normal
|
||||
* full navigation. `push` adds a history entry (false when replaying popstate).
|
||||
@@ -402,6 +418,30 @@ function navigate(pathname, push, kbd) {
|
||||
const className = tree.viewClassFor(node);
|
||||
if (!className)
|
||||
return false;
|
||||
|
||||
/* A PAGE WHOSE STYLESHEET ONLY THE SERVER CAN EMIT IS NOT OURS TO SWAP INTO.
|
||||
*
|
||||
* A menu.d node may name its own sheet (`"css": "view/foo/foo.css"`), and the server links it
|
||||
* from <head> on a full load (partials/head.ut). Nothing here can: a swap replaces #view's
|
||||
* children, it does not re-render a document, so reaching such a page by CLICK would show it
|
||||
* with the app's CSS missing — while reaching the same page by URL or F5 showed it styled. One
|
||||
* page, two appearances, decided by how the user got there.
|
||||
*
|
||||
* So decline, exactly as the poisoned-document bail above does: speed is traded for
|
||||
* correctness, never the other way. It costs ONE full load per such page — after it the <link>
|
||||
* is in the document, this test passes, and every later visit is a swap again (fs-sheets.js
|
||||
* owns the sheet from then on and re-lights it per page).
|
||||
*
|
||||
* Injecting the <link> here instead would work and is deliberately not done: it would put the
|
||||
* theme in charge of fetching and ordering a foreign stylesheet, which is the job fs-sheets.js
|
||||
* exists to keep out of the theme. The server already does it correctly.
|
||||
*
|
||||
* `node.css` reaches the client because /admin/menu serves the dispatcher's own tree and
|
||||
* ui.js's scrubMenu() only rewrites `satisfied`. On a luci-base that predates the `css` schema
|
||||
* entry the property is dropped server-side, so this is simply never true there. */
|
||||
if (typeof node.css === 'string' && node.css !== '' && !documentHasSheet(node.css))
|
||||
return false;
|
||||
|
||||
const rsegs = res.segs;
|
||||
|
||||
/* from here on the navigation is committed */
|
||||
|
||||
@@ -15,21 +15,26 @@
|
||||
* cutting in half. The fields shrink instead of forcing that: `min-width: 0` undoes the field
|
||||
* box in theme/60-inputs.css for this row only.
|
||||
*
|
||||
* Keyed on the controls' OWN ids rather than on the page: `data-page` differs between the system
|
||||
* and the kernel log, and a third-party LogreadBox has neither, while ui.js gives these two rows
|
||||
* the same ids wherever the widget is rendered. The inline `margin: 0 5px` LuCI writes on the
|
||||
* labels stays as the horizontal spacing — only the ROW gap is ours, so nothing here has to
|
||||
* fight an inline style. */
|
||||
div:has(> #logFacilitySelect),
|
||||
div:has(> #logTextFilter) {
|
||||
* Keyed on the ROW's SHAPE, not on the page and not on the controls' ids. `data-page` differs
|
||||
* between the system and the kernel log and a third-party LogreadBox has neither — but the ids
|
||||
* are no better: only the System Log is built by `tools/views.js`, and Status → Kernel Log is a
|
||||
* view of its own (`view/status/dmesg.js`) whose four rows carry `logFromTime`, `logToTime`,
|
||||
* `invertLogRangeTime`, `invertSeverity` and `invertAscendingSort`, of which an id list written
|
||||
* against LogreadBox catches none — `logFacilitySelect` appears there only as a `for=`, on a
|
||||
* label whose control is a time field. Both views wrap their rows in `#content_syslog`, and a
|
||||
* filter row is exactly one that opens with a `<label>`; the scroll-to-end button's row and the
|
||||
* log itself do not. That shape holds for any view built the same way.
|
||||
*
|
||||
* The inline `margin: 0 5px` LuCI writes on the labels stays as the horizontal spacing — only
|
||||
* the ROW gap is ours, so nothing here has to fight an inline style. */
|
||||
#content_syslog > div:has(> label) {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
row-gap: var(--fs-space-2);
|
||||
}
|
||||
div:has(> #logFacilitySelect) > label,
|
||||
div:has(> #logTextFilter) > label { white-space: nowrap; }
|
||||
#logFacilitySelect, #logSeveritySelect, #logTextFilter, #logMaxRows {
|
||||
#content_syslog > div:has(> label) > label { white-space: nowrap; }
|
||||
#content_syslog > div:has(> label) > :is(select, input) {
|
||||
flex: 1 1 auto;
|
||||
/* both halves are needed and they answer different layouts: `min-width: 0` lets a FLEX item
|
||||
* shrink past its content, `max-width: 100%` clamps a GRID item to its track. A <select>
|
||||
@@ -38,6 +43,8 @@
|
||||
min-width: 0;
|
||||
max-width: 100%;
|
||||
}
|
||||
/* a checkbox is not a field: left to its own 16px, it would otherwise flex to fill the line. */
|
||||
#content_syslog > div:has(> label) > input[type="checkbox"] { flex: 0 0 auto; }
|
||||
/* the two numeric-ish fields keep a sane ceiling: a max-rows box as wide as the filter reads as
|
||||
* a second search field. */
|
||||
#logMaxRows { flex-basis: 6ch; max-width: 12ch; }
|
||||
@@ -47,12 +54,18 @@
|
||||
* first row is a fixed alternation of exactly two filters — invert label, checkbox, name label,
|
||||
* control, twice — so a four-column grid puts one filter on each line.
|
||||
*
|
||||
* The SECOND row is deliberately left to the wrapping above. It holds two filters of different
|
||||
* shapes (a checkbox filter and a bare `Макс. строк:` pair), so the same four tracks would be
|
||||
* sized by items that are not each other's counterparts: measured, the max-rows box defined
|
||||
* column 2 and pushed `содержит:` and its field off the card. Wrapping puts that row's two
|
||||
* filters on two lines by itself, which is all the grid was for. */
|
||||
* EVERY OTHER ROW is deliberately left to the wrapping above, because none of them is that
|
||||
* shape. The System Log's second row holds a checkbox filter beside a bare `Макс. строк:` pair,
|
||||
* and the same four tracks are then sized by items that are not each other's counterparts:
|
||||
* measured, the max-rows box defined column 2 and pushed `содержит:` and its field off the card.
|
||||
* The Kernel Log's rows are three different shapes again — a range with two time fields, a
|
||||
* severity select with a trailing `and above`, and a lone sort checkbox. Wrapping puts each of
|
||||
* those on as many lines as it needs, which is all the grid was ever for; the grid is worth its
|
||||
* one selector only where the alternation is exact. */
|
||||
@container fs-view (max-width: 560px) {
|
||||
/* the id alone, without `#content_syslog >` in front of it: two ids in one selector is
|
||||
* [2,0,1], past the [1,7,0] ceiling `npm run css-metrics` holds the sheet to, and the row is
|
||||
* already pinned down by the only id LuCI puts on that select. */
|
||||
div:has(> #logFacilitySelect) {
|
||||
display: grid;
|
||||
grid-template-columns: auto auto auto minmax(0, 1fr);
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=modeminfo
|
||||
PKG_VERSION:=0.4.7
|
||||
PKG_RELEASE:=9
|
||||
PKG_VERSION:=0.4.8
|
||||
PKG_RELEASE:=10
|
||||
PKG_MAINTAINER:=Konstantine Shevlakov <shevlakov@132lan.ru>
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
@@ -42,6 +42,9 @@
|
||||
# Telit LN940 LT4220
|
||||
1bc71900;QUALCOMM
|
||||
1bc71901;QUALCOMM
|
||||
# Telit LM960
|
||||
1bc71040;QUALCOMM_LM960
|
||||
1bc71041;QUALCOMM_LM960
|
||||
# Yuge CLM920
|
||||
12864e3c;YUGE
|
||||
# ThinkWill ML7820
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
# Qualcomm Modems (FoxConn T77W678, Telit LN940, HP LT4220)
|
||||
function modem_data(){
|
||||
generic_data
|
||||
# hwinfo and siminfo
|
||||
FAMILY_EX="Telit"
|
||||
OIFS="$IFS"; IFS="|"
|
||||
set -- $(echo "$O" | awk -v fam="$FAMILY_EX" '
|
||||
($0 ~ fam){manuf =$0; getline model; getline fw}
|
||||
/ICCID:/{split($0,i,":");gsub("\r",""); iccid=i[2]; getline imsi; getline imei}
|
||||
/TSENS2/{split($0,i,",");temp=i[2]}
|
||||
END{print manuf "|" model "|" fw "|" iccid "|" imsi "|" imei "|" temp}
|
||||
')
|
||||
MANUF=${1}; MODEL=${2}; FW=${3}; ICCID=${4}; IMSI=${5} IMEI=${6}; CHIPTEMP=${7}
|
||||
IFS="$OIFS"; unset OIFS
|
||||
DEVICE="$MANUF $MODEL"
|
||||
OIFS="$IFS"; IFS="|"
|
||||
# signal
|
||||
set -- $(echo "$O" | awk -v mode="$MODE" '
|
||||
BEGIN { map[1]=3; map[2]=5; map[3]=10; map[4]=15; map[5]=20 }
|
||||
mode ~ /LTE/ { # LTE mode
|
||||
if (/\+CEREG/){gsub("\"",""); split($0,i,","); reg=i[2]; lac=i[3]; cid=i[4]}
|
||||
if (/CAINFO:/){ split($0,i,","); earfcn=i[2]; rssi=sprintf("%.0f",i[6]); rsrp=sprintf("%.0f",i[5]);
|
||||
sinr=sprintf("%.0f",i[8]/5-20); rsrq=sprintf("%.0f",i[7]); pci=i[4]; bw=sprintf("%.0f",i[3]);
|
||||
lte_ca=i[15]; bwc=map[bw]
|
||||
}
|
||||
if (/PCC info/){bwc=sprintf("%.0f",$(NF-1)); bw=map[bwc]}
|
||||
cell = sprintf("%d", "0x" substr(cid, length(cid) - 1, 2))
|
||||
enbid = sprintf("%d", "0x" substr(cid, 1, length(cid) - 2))
|
||||
}
|
||||
mode !~ /LTE/ { # 3G mode
|
||||
if (/\+CREG/){gsub("\"",""); split($0,i,","); reg=i[2]; lac=i[3]; cid=i[4]}
|
||||
if (/RFSTS:/){ split($0,i,","); earfcn=i[2]; rssi=sprintf("%.0f",i[6]); sinr=sprintf("%.0f",i[4])}
|
||||
}
|
||||
END { print reg "|" earfcn "|" lac "|" cid "|" rssi "|" sinr "|" rsrp "|" rsrq "|" pci "|" bw "|" bwc "|" lte_ca "|" enbid "|" cell}
|
||||
')
|
||||
EARFCN=${2}; LAC=${3}; CID=${4}; CSQ_RSSI=${5}; SINR=${6}; RSRP=${7}; RSRQ=${8}; PCI=${9}; BWDL=${10}; BWDx=${11}; LTE_CA=${12}; ENBID=${13}; CELL=${14}
|
||||
IFS="$OIFS"; unset OIFS
|
||||
# LTE CA calc
|
||||
if [ $LTE_CA -ne 0 ]; then
|
||||
OIFS="$IFS"; IFS="|"
|
||||
set -- $(echo "$O" | awk -F"," -v bwc=${BWDx:=0} -v mode=$MODE '
|
||||
BEGIN { map[1]=3; map[2]=5; map[3]=10; map[4]=15; map[5]=20 }
|
||||
function earfcn_to_band(channel) {
|
||||
if (channel <= 1) return ""
|
||||
cmd = "/usr/share/modeminfo/scripts/ch_to_band " mode " " channel
|
||||
cmd | getline band
|
||||
close(cmd)
|
||||
return band
|
||||
}
|
||||
/CAINFO:/{
|
||||
ch[1]=14; ch[2]=25; ch[3]=36; ch[4]=47
|
||||
bw[1]=15; bw[2]=26; bw[3]=37; bw[4]=48
|
||||
scc = ""; bwcx = 0
|
||||
for(i=1;i<=4;i++) {
|
||||
if($ch[i]!=0) {
|
||||
scc=scc"+"earfcn_to_band($ch[i])
|
||||
bwcx=map[$bw[i]]
|
||||
bwca+=bwcx
|
||||
}
|
||||
}
|
||||
bwca=bwca+bwc
|
||||
print scc"|"bwca
|
||||
}
|
||||
')
|
||||
SCC=${1}; BWCA=${2}
|
||||
IFS="$OIFS"; unset OIFS BWDx
|
||||
fi
|
||||
|
||||
if [ $(uci -q get modeminfo.@general[0].decimail) = "1" ]; then
|
||||
LAC=$(printf %d 0x$LAC)
|
||||
CID=$(printf %d 0x$CID)
|
||||
fi
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
ATE0
|
||||
AT+COPS=3,0; +COPS?
|
||||
AT+CREG=2; +CREG?
|
||||
AT+CGREG=2; +CGREG?
|
||||
AT+CEREG=2; +CEREG?
|
||||
AT+CSQ
|
||||
AT#RFSTS
|
||||
AT#CAINFO?
|
||||
AT+CGMI; +CGMM; +CGMR; +ICCID; +CIMI; +CGSN
|
||||
AT#TEMPSENS=2
|
||||
+2
-2
@@ -10,12 +10,12 @@ include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=natflow
|
||||
PKG_VERSION:=20260531
|
||||
PKG_RELEASE:=62
|
||||
PKG_RELEASE:=63
|
||||
|
||||
PKG_SOURCE:=$(PKG_VERSION).tar.xz
|
||||
PKG_SOURCE_URL:=https://github.com/ptpt52/natflow.git
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_VERSION:=00be1cea6bcdaf0d8e79b62dff533f08f49863e8
|
||||
PKG_SOURCE_VERSION:=a2e7cbafc787ba9a0e86550bd3f4d03207fb9678
|
||||
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
|
||||
PKG_MAINTAINER:=Chen Minqiang <ptpt52@gmail.com>
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
|
||||
Reference in New Issue
Block a user