luci-app-ddns: improve performance

Every request directed to the ddns app call ddns tools module.
Ddns tools module have lots of global variable that call slow os.execute function. This adds 10 second to every ddns request even if the function that is requested doesn't need that global variable. This commit introduce env_info function that execute os.execute command by executing what is actually requested and not process all the variables. Also remove 2 unecessary module that are not used. More researh find that major slowdown was caused by the calling of ddns script for the version check. Now we check if opkg is present and use it to check ddns-scripts version.

Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
This commit is contained in:
Ansuel Smith 2018-05-24 02:03:03 +02:00
parent 7acacf2cf8
commit 299121fc84
No known key found for this signature in database
GPG key ID: AC001D09ADBFEAD7
6 changed files with 230 additions and 96 deletions

View file

@ -16,7 +16,7 @@ PKG_VERSION:=2.4.9
# Release == build # Release == build
# increase on changes of translation files # increase on changes of translation files
PKG_RELEASE:=3 PKG_RELEASE:=4
PKG_LICENSE:=Apache-2.0 PKG_LICENSE:=Apache-2.0
PKG_MAINTAINER:=Christian Schoenebeck <christian.schoenebeck@gmail.com> PKG_MAINTAINER:=Christian Schoenebeck <christian.schoenebeck@gmail.com>

View file

@ -21,7 +21,6 @@ luci_helper = "/usr/lib/ddns/dynamic_dns_lucihelper.sh"
local srv_name = "ddns-scripts" local srv_name = "ddns-scripts"
local srv_ver_min = "2.7.7" -- minimum version of service required local srv_ver_min = "2.7.7" -- minimum version of service required
local srv_ver_cmd = luci_helper .. [[ -V | awk {'print $2'}]]
local app_name = "luci-app-ddns" local app_name = "luci-app-ddns"
local app_title = "Dynamic DNS" local app_title = "Dynamic DNS"
local app_version = "2.4.9-1" local app_version = "2.4.9-1"
@ -29,7 +28,6 @@ local app_version = "2.4.9-1"
function index() function index()
local nxfs = require "nixio.fs" -- global definitions not available local nxfs = require "nixio.fs" -- global definitions not available
local sys = require "luci.sys" -- in function index() local sys = require "luci.sys" -- in function index()
local ddns = require "luci.tools.ddns" -- ddns multiused functions
local muci = require "luci.model.uci" local muci = require "luci.model.uci"
-- no config create an empty one -- no config create an empty one
@ -81,26 +79,41 @@ end
-- Standardized application/service functions -- Standardized application/service functions
function app_title_main() function app_title_main()
return [[<a href="javascript:alert(']] tmp = {}
.. I18N.translate("Version Information") tmp[#tmp+1] = [[<a href="javascript:alert(']]
.. [[\n\n]] .. app_name tmp[#tmp+1] = I18N.translate("Version Information")
.. [[\n\t]] .. I18N.translate("Version") .. [[:\t]] .. app_version tmp[#tmp+1] = [[\n\n]] .. app_name
.. [[\n\n]] .. srv_name .. [[ ]] .. I18N.translate("required") .. [[:]] tmp[#tmp+1] = [[\n\t]] .. I18N.translate("Version") .. [[:\t]] .. app_version
.. [[\n\t]] .. I18N.translate("Version") .. [[:\t]] tmp[#tmp+1] = [[\n\n]] .. srv_name .. [[ ]] .. I18N.translate("required") .. [[:]]
.. srv_ver_min .. [[ ]] .. I18N.translate("or higher") tmp[#tmp+1] = [[\n\t]] .. I18N.translate("Version") .. [[:\t]]
.. [[\n\n]] .. srv_name .. [[ ]] .. I18N.translate("installed") .. [[:]] tmp[#tmp+1] = srv_ver_min .. [[ ]] .. I18N.translate("or higher")
.. [[\n\t]] .. I18N.translate("Version") .. [[:\t]] tmp[#tmp+1] = [[\n\n]] .. srv_name .. [[ ]] .. I18N.translate("installed") .. [[:]]
.. (service_version() or I18N.translate("NOT installed")) tmp[#tmp+1] = [[\n\t]] .. I18N.translate("Version") .. [[:\t]]
.. [[\n\n]] tmp[#tmp+1] = (service_version() or I18N.translate("NOT installed"))
.. [[')">]] tmp[#tmp+1] = [[\n\n]]
.. I18N.translate(app_title) tmp[#tmp+1] = [[')">]]
.. [[</a>]] tmp[#tmp+1] = I18N.translate(app_title)
tmp[#tmp+1] = [[</a>]]
return table.concat(tmp)
end end
function service_version() function service_version()
local ver = nil
local nxfs = require "nixio.fs"
local ver = nil
local ver_helper
if nxfs.access("/bin/opkg") then
ver_helper = "/bin/opkg info " .. srv_name .. " | grep 'Version'"
else
ver_helper = luci_helper .. " -V"
end
local srv_ver_cmd = ver_helper .. " | awk {'print $2'} "
ver = UTIL.exec(srv_ver_cmd) ver = UTIL.exec(srv_ver_cmd)
if #ver > 0 then return ver end if ver and #ver > 0 then return ver end
IPKG.list_installed(srv_name, function(n, v, d) IPKG.list_installed(srv_name, function(n, v, d)
if v and (#v > 0) then ver = v end if v and (#v > 0) then ver = v end
@ -108,6 +121,7 @@ function service_version()
) )
return ver return ver
end end
function service_ok() function service_ok()
return IPKG.compare_versions((service_version() or "0"), ">=", srv_ver_min) return IPKG.compare_versions((service_version() or "0"), ">=", srv_ver_min)
end end

View file

@ -292,6 +292,10 @@ function luh.parse(self, section, novld)
end end
-- use_ipv6 -- ################################################################ -- use_ipv6 -- ################################################################
--We call it globally as it's called 11 times even outside specific function, saves 11 os.execute slow command!
local has_ipv6 = DDNS.env_info("has_ipv6")
usev6 = ns:taboption("basic", ListValue, "use_ipv6", usev6 = ns:taboption("basic", ListValue, "use_ipv6",
translate("IP address version"), translate("IP address version"),
translate("Defines which IP address 'IPv4/IPv6' is send to the DDNS provider") ) translate("Defines which IP address 'IPv4/IPv6' is send to the DDNS provider") )
@ -300,16 +304,16 @@ usev6.default = "0"
usev6:value("0", translate("IPv4-Address") ) usev6:value("0", translate("IPv4-Address") )
function usev6.cfgvalue(self, section) function usev6.cfgvalue(self, section)
local value = AbstractValue.cfgvalue(self, section) or "0" local value = AbstractValue.cfgvalue(self, section) or "0"
if DDNS.has_ipv6 or (value == "1" and not DDNS.has_ipv6) then if has_ipv6 or (value == "1" and not has_ipv6) then
self:value("1", translate("IPv6-Address") ) self:value("1", translate("IPv6-Address") )
end end
if value == "1" and not DDNS.has_ipv6 then if value == "1" and not has_ipv6 then
self.description = err_ipv6_basic self.description = err_ipv6_basic
end end
return value return value
end end
function usev6.validate(self, value) function usev6.validate(self, value)
if (value == "1" and DDNS.has_ipv6) or value == "0" then if (value == "1" and has_ipv6) or value == "0" then
return value return value
end end
return nil, err_tab_basic(self) .. err_ipv6_plain return nil, err_tab_basic(self) .. err_ipv6_plain
@ -360,7 +364,7 @@ svc6 = ns:taboption("basic", ListValue, "ipv6_service_name",
translate("DDNS Service provider") .. " [IPv6]" ) translate("DDNS Service provider") .. " [IPv6]" )
svc6.default = "-" svc6.default = "-"
svc6:depends("use_ipv6", "1") -- only show on IPv6 svc6:depends("use_ipv6", "1") -- only show on IPv6
if not DDNS.has_ipv6 then if not has_ipv6 then
svc6.description = err_ipv6_basic svc6.description = err_ipv6_basic
end end
function svc6.cfgvalue(self, section) function svc6.cfgvalue(self, section)
@ -374,7 +378,7 @@ function svc6.cfgvalue(self, section)
end end
function svc6.validate(self, value) function svc6.validate(self, value)
if usev6:formvalue(section) == "1" then -- do only on IPv6 if usev6:formvalue(section) == "1" then -- do only on IPv6
if DDNS.has_ipv6 then return value end if has_ipv6 then return value end
return nil, err_tab_basic(self) .. err_ipv6_plain return nil, err_tab_basic(self) .. err_ipv6_plain
else else
return "" -- suppress validate error return "" -- suppress validate error
@ -586,13 +590,17 @@ end
svc6:value("-", translate("-- custom --") ) svc6:value("-", translate("-- custom --") )
-- IPv4/IPv6 - use_https -- ################################################### -- IPv4/IPv6 - use_https -- ###################################################
if DDNS.has_ssl or ( ( m:get(section, "use_https") or "0" ) == "1" ) then
--We call it globally as it's called 4 times outside specific function.
local has_ssl = DDNS.env_info("has_ssl")
if has_ssl or ( ( m:get(section, "use_https") or "0" ) == "1" ) then
https = ns:taboption("basic", Flag, "use_https", https = ns:taboption("basic", Flag, "use_https",
translate("Use HTTP Secure") ) translate("Use HTTP Secure") )
https.orientation = "horizontal" https.orientation = "horizontal"
function https.cfgvalue(self, section) function https.cfgvalue(self, section)
local value = AbstractValue.cfgvalue(self, section) local value = AbstractValue.cfgvalue(self, section)
if not DDNS.has_ssl and value == "1" then if not has_ssl and value == "1" then
self.description = bold_on .. font_red .. self.description = bold_on .. font_red ..
translate("HTTPS not supported") .. font_off .. "<br />" .. translate("HTTPS not supported") .. font_off .. "<br />" ..
translate("please disable") .. " !" .. bold_off translate("please disable") .. " !" .. bold_off
@ -602,7 +610,7 @@ if DDNS.has_ssl or ( ( m:get(section, "use_https") or "0" ) == "1" ) then
return value return value
end end
function https.validate(self, value) function https.validate(self, value)
if (value == "1" and DDNS.has_ssl ) or value == "0" then return value end if (value == "1" and has_ssl ) or value == "0" then return value end
return nil, err_tab_basic(self) .. translate("HTTPS not supported") .. " !" return nil, err_tab_basic(self) .. translate("HTTPS not supported") .. " !"
end end
function https.write(self, section, value) function https.write(self, section, value)
@ -616,7 +624,7 @@ if DDNS.has_ssl or ( ( m:get(section, "use_https") or "0" ) == "1" ) then
end end
-- IPv4/IPv6 - cacert -- ###################################################### -- IPv4/IPv6 - cacert -- ######################################################
if DDNS.has_ssl then if has_ssl then
cert = ns:taboption("basic", Value, "cacert", cert = ns:taboption("basic", Value, "cacert",
translate("Path to CA-Certificate"), translate("Path to CA-Certificate"),
translate("directory or path/file") .. "<br />" .. translate("directory or path/file") .. "<br />" ..
@ -706,7 +714,7 @@ src6:value("network", translate("Network"))
src6:value("web", translate("URL")) src6:value("web", translate("URL"))
src6:value("interface", translate("Interface")) src6:value("interface", translate("Interface"))
src6:value("script", translate("Script")) src6:value("script", translate("Script"))
if not DDNS.has_ipv6 then if not has_ipv6 then
src6.description = err_ipv6_other src6.description = err_ipv6_other
end end
function src6.cfgvalue(self, section) function src6.cfgvalue(self, section)
@ -715,7 +723,7 @@ end
function src6.validate(self, value) function src6.validate(self, value)
if usev6:formvalue(section) ~= "1" then if usev6:formvalue(section) ~= "1" then
return "" -- ignore on IPv4 selected return "" -- ignore on IPv4 selected
elseif not DDNS.has_ipv6 then elseif not has_ipv6 then
return nil, err_tab_adv(self) .. err_ipv6_plain return nil, err_tab_adv(self) .. err_ipv6_plain
elseif not _verify_ip_source() then elseif not _verify_ip_source() then
return nil, err_tab_adv(self) .. return nil, err_tab_adv(self) ..
@ -794,7 +802,7 @@ ipn6 = ns:taboption("advanced", ListValue, "ipv6_network",
ipn6:depends("ipv6_source", "network") ipn6:depends("ipv6_source", "network")
ipn6.default = "wan6" ipn6.default = "wan6"
WADM.cbi_add_networks(ipn6) WADM.cbi_add_networks(ipn6)
if DDNS.has_ipv6 then if has_ipv6 then
ipn6.description = translate("Defines the network to read systems IPv6-Address from") ipn6.description = translate("Defines the network to read systems IPv6-Address from")
else else
ipn6.description = err_ipv6_other ipn6.description = err_ipv6_other
@ -808,7 +816,7 @@ function ipn6.validate(self, value)
-- ignore if IPv4 selected OR -- ignore if IPv4 selected OR
-- ignore everything except "network" -- ignore everything except "network"
return "" return ""
elseif DDNS.has_ipv6 then elseif has_ipv6 then
return value return value
else else
return nil, err_tab_adv(self) .. err_ipv6_plain return nil, err_tab_adv(self) .. err_ipv6_plain
@ -881,7 +889,7 @@ iurl6 = ns:taboption("advanced", Value, "ipv6_url",
translate("URL to detect") .. " [IPv6]" ) translate("URL to detect") .. " [IPv6]" )
iurl6:depends("ipv6_source", "web") iurl6:depends("ipv6_source", "web")
iurl6.default = "http://checkipv6.dyndns.com" iurl6.default = "http://checkipv6.dyndns.com"
if DDNS.has_ipv6 then if has_ipv6 then
iurl6.description = translate("Defines the Web page to read systems IPv6-Address from") iurl6.description = translate("Defines the Web page to read systems IPv6-Address from")
else else
iurl6.description = err_ipv6_other iurl6.description = err_ipv6_other
@ -895,7 +903,7 @@ function iurl6.validate(self, value)
-- ignore if IPv4 selected OR -- ignore if IPv4 selected OR
-- ignore everything except "web" -- ignore everything except "web"
return "" return ""
elseif not DDNS.has_ipv6 then elseif not has_ipv6 then
return nil, err_tab_adv(self) .. err_ipv6_plain return nil, err_tab_adv(self) .. err_ipv6_plain
elseif not value or #value == 0 then elseif not value or #value == 0 then
return nil, err_tab_adv(self) .. translate("missing / required") return nil, err_tab_adv(self) .. translate("missing / required")
@ -1051,7 +1059,7 @@ eif6:depends("ipv6_source", "web")
eif6:depends("ipv6_source", "script") eif6:depends("ipv6_source", "script")
eif6.default = "wan6" eif6.default = "wan6"
WADM.cbi_add_networks(eif6) WADM.cbi_add_networks(eif6)
if not DDNS.has_ipv6 then if not has_ipv6 then
eif6.description = err_ipv6_other eif6.description = err_ipv6_other
else else
eif6.description = translate("Network on which the ddns-updater scripts will be started") eif6.description = translate("Network on which the ddns-updater scripts will be started")
@ -1065,7 +1073,7 @@ function eif6.validate(self, value)
or fsrc6 == "network" or fsrc6 == "network"
or fsrc6 == "interface" then or fsrc6 == "interface" then
return "" -- ignore IPv4, network, interface return "" -- ignore IPv4, network, interface
elseif not DDNS.has_ipv6 then elseif not has_ipv6 then
return nil, err_tab_adv(self) .. err_ipv6_plain return nil, err_tab_adv(self) .. err_ipv6_plain
else else
return value return value
@ -1084,10 +1092,13 @@ function eif6.write(self, section, value)
end end
function eif6.parse(self, section, novld) function eif6.parse(self, section, novld)
DDNS.value_parse(self, section, novld) DDNS.value_parse(self, section, novld)
end end
-- IPv4/IPv6 - bind_network -- ################################################ -- IPv4/IPv6 - bind_network -- ################################################
if DDNS.has_bindnet or ( ( m:get(section, "bind_network") or "" ) ~= "" ) then
local has_bindnet = DDNS.env_info("has_bindnet")
if has_bindnet or ( ( m:get(section, "bind_network") or "" ) ~= "" ) then
bnet = ns:taboption("advanced", ListValue, "bind_network", bnet = ns:taboption("advanced", ListValue, "bind_network",
translate("Bind Network") ) translate("Bind Network") )
bnet:depends("ipv4_source", "web") bnet:depends("ipv4_source", "web")
@ -1097,7 +1108,7 @@ if DDNS.has_bindnet or ( ( m:get(section, "bind_network") or "" ) ~= "" ) then
WADM.cbi_add_networks(bnet) WADM.cbi_add_networks(bnet)
function bnet.cfgvalue(self, section) function bnet.cfgvalue(self, section)
local value = AbstractValue.cfgvalue(self, section) local value = AbstractValue.cfgvalue(self, section)
if not DDNS.has_bindnet and value ~= "" then if not has_bindnet and value ~= "" then
self.description = bold_on .. font_red .. self.description = bold_on .. font_red ..
translate("Binding to a specific network not supported") .. font_off .. "<br />" .. translate("Binding to a specific network not supported") .. font_off .. "<br />" ..
translate("please set to 'default'") .. " !" .. bold_off translate("please set to 'default'") .. " !" .. bold_off
@ -1108,7 +1119,7 @@ if DDNS.has_bindnet or ( ( m:get(section, "bind_network") or "" ) ~= "" ) then
return value return value
end end
function bnet.validate(self, value) function bnet.validate(self, value)
if ( (value ~= "") and DDNS.has_bindnet ) or (value == "") then return value end if ( (value ~= "") and has_bindnet ) or (value == "") then return value end
return nil, err_tab_adv(self) .. translate("Binding to a specific network not supported") .. " !" return nil, err_tab_adv(self) .. translate("Binding to a specific network not supported") .. " !"
end end
function bnet.parse(self, section, novld) function bnet.parse(self, section, novld)
@ -1119,13 +1130,16 @@ end
-- IPv4 + IPv6 - force_ipversion -- ########################################### -- IPv4 + IPv6 - force_ipversion -- ###########################################
-- optional to force wget/curl and host to use only selected IP version -- optional to force wget/curl and host to use only selected IP version
-- command parameter "-4" or "-6" -- command parameter "-4" or "-6"
if DDNS.has_forceip or ( ( m:get(section, "force_ipversion") or "0" ) ~= "0" ) then
local has_forceip = DDNS.env_info("has_forceip")
if has_forceip or ( ( m:get(section, "force_ipversion") or "0" ) ~= "0" ) then
fipv = ns:taboption("advanced", Flag, "force_ipversion", fipv = ns:taboption("advanced", Flag, "force_ipversion",
translate("Force IP Version") ) translate("Force IP Version") )
fipv.orientation = "horizontal" fipv.orientation = "horizontal"
function fipv.cfgvalue(self, section) function fipv.cfgvalue(self, section)
local value = AbstractValue.cfgvalue(self, section) local value = AbstractValue.cfgvalue(self, section)
if not DDNS.has_forceip and value ~= "0" then if not has_forceip and value ~= "0" then
self.description = bold_on .. font_red .. self.description = bold_on .. font_red ..
translate("Force IP Version not supported") .. font_off .. "<br />" .. translate("Force IP Version not supported") .. font_off .. "<br />" ..
translate("please disable") .. " !" .. bold_off translate("please disable") .. " !" .. bold_off
@ -1135,14 +1149,17 @@ if DDNS.has_forceip or ( ( m:get(section, "force_ipversion") or "0" ) ~= "0" ) t
return value return value
end end
function fipv.validate(self, value) function fipv.validate(self, value)
if (value == "1" and DDNS.has_forceip) or value == "0" then return value end if (value == "1" and has_forceip) or value == "0" then return value end
return nil, err_tab_adv(self) .. translate("Force IP Version not supported") return nil, err_tab_adv(self) .. translate("Force IP Version not supported")
end end
end end
-- IPv4 + IPv6 - dns_server -- ################################################ -- IPv4 + IPv6 - dns_server -- ################################################
-- optional DNS Server to use resolving my IP -- optional DNS Server to use resolving my IP
if DDNS.has_dnsserver or ( ( m:get(section, "dns_server") or "" ) ~= "" ) then
local has_dnsserver = DDNS.env_info("has_dnsserver")
if has_dnsserver or ( ( m:get(section, "dns_server") or "" ) ~= "" ) then
dns = ns:taboption("advanced", Value, "dns_server", dns = ns:taboption("advanced", Value, "dns_server",
translate("DNS-Server"), translate("DNS-Server"),
translate("OPTIONAL: Use non-default DNS-Server to detect 'Registered IP'.") .. "<br />" .. translate("OPTIONAL: Use non-default DNS-Server to detect 'Registered IP'.") .. "<br />" ..
@ -1152,7 +1169,7 @@ if DDNS.has_dnsserver or ( ( m:get(section, "dns_server") or "" ) ~= "" ) then
-- if .datatype is set, then it is checked before calling this function -- if .datatype is set, then it is checked before calling this function
if not value or (#value == 0) then if not value or (#value == 0) then
return "" -- ignore on empty return "" -- ignore on empty
elseif not DDNS.has_dnsserver then elseif not has_dnsserver then
return nil, err_tab_adv(self) .. translate("Specifying a DNS-Server is not supported") return nil, err_tab_adv(self) .. translate("Specifying a DNS-Server is not supported")
elseif not DTYP.host(value) then elseif not DTYP.host(value) then
return nil, err_tab_adv(self) .. translate("use hostname, FQDN, IPv4- or IPv6-Address") return nil, err_tab_adv(self) .. translate("use hostname, FQDN, IPv4- or IPv6-Address")
@ -1179,13 +1196,16 @@ if DDNS.has_dnsserver or ( ( m:get(section, "dns_server") or "" ) ~= "" ) then
end end
-- IPv4 + IPv6 - force_dnstcp -- ############################################## -- IPv4 + IPv6 - force_dnstcp -- ##############################################
if DDNS.has_bindhost or ( ( m:get(section, "force_dnstcp") or "0" ) ~= "0" ) then
local has_bindhost = DDNS.env_info("has_bindhost")
if has_bindhost or ( ( m:get(section, "force_dnstcp") or "0" ) ~= "0" ) then
tcp = ns:taboption("advanced", Flag, "force_dnstcp", tcp = ns:taboption("advanced", Flag, "force_dnstcp",
translate("Force TCP on DNS") ) translate("Force TCP on DNS") )
tcp.orientation = "horizontal" tcp.orientation = "horizontal"
function tcp.cfgvalue(self, section) function tcp.cfgvalue(self, section)
local value = AbstractValue.cfgvalue(self, section) local value = AbstractValue.cfgvalue(self, section)
if not DDNS.has_bindhost and value ~= "0" then if not has_bindhost and value ~= "0" then
self.description = bold_on .. font_red .. self.description = bold_on .. font_red ..
translate("DNS requests via TCP not supported") .. font_off .. "<br />" .. translate("DNS requests via TCP not supported") .. font_off .. "<br />" ..
translate("please disable") .. " !" .. bold_off translate("please disable") .. " !" .. bold_off
@ -1195,7 +1215,7 @@ if DDNS.has_bindhost or ( ( m:get(section, "force_dnstcp") or "0" ) ~= "0" ) the
return value return value
end end
function tcp.validate(self, value) function tcp.validate(self, value)
if (value == "1" and DDNS.has_bindhost ) or value == "0" then if (value == "1" and has_bindhost ) or value == "0" then
return value return value
end end
return nil, err_tab_adv(self) .. translate("DNS requests via TCP not supported") return nil, err_tab_adv(self) .. translate("DNS requests via TCP not supported")
@ -1204,13 +1224,16 @@ end
-- IPv4 + IPv6 - proxy -- ##################################################### -- IPv4 + IPv6 - proxy -- #####################################################
-- optional Proxy to use for http/https requests [user:password@]proxyhost[:port] -- optional Proxy to use for http/https requests [user:password@]proxyhost[:port]
if DDNS.has_proxy or ( ( m:get(section, "proxy") or "" ) ~= "" ) then
local has_proxy = DDNS.env_info("has_proxy")
if has_proxy or ( ( m:get(section, "proxy") or "" ) ~= "" ) then
pxy = ns:taboption("advanced", Value, "proxy", pxy = ns:taboption("advanced", Value, "proxy",
translate("PROXY-Server") ) translate("PROXY-Server") )
pxy.placeholder="user:password@myproxy.lan:8080" pxy.placeholder="user:password@myproxy.lan:8080"
function pxy.cfgvalue(self, section) function pxy.cfgvalue(self, section)
local value = AbstractValue.cfgvalue(self, section) local value = AbstractValue.cfgvalue(self, section)
if not DDNS.has_proxy and value ~= "" then if not has_proxy and value ~= "" then
self.description = bold_on .. font_red .. self.description = bold_on .. font_red ..
translate("PROXY-Server not supported") .. font_off .. "<br />" .. translate("PROXY-Server not supported") .. font_off .. "<br />" ..
translate("please remove entry") .. "!" .. bold_off translate("please remove entry") .. "!" .. bold_off
@ -1226,7 +1249,7 @@ if DDNS.has_proxy or ( ( m:get(section, "proxy") or "" ) ~= "" ) then
-- if .datatype is set, then it is checked before calling this function -- if .datatype is set, then it is checked before calling this function
if not value or (#value == 0) then if not value or (#value == 0) then
return "" -- ignore on empty return "" -- ignore on empty
elseif DDNS.has_proxy then elseif has_proxy then
local ipv6 = usev6:formvalue(section) or "0" local ipv6 = usev6:formvalue(section) or "0"
local force = fipv:formvalue(section) or "0" local force = fipv:formvalue(section) or "0"
local command = CTRL.luci_helper .. [[ -]] local command = CTRL.luci_helper .. [[ -]]

View file

@ -48,7 +48,7 @@ if not SYS.init.enabled("ddns") then
end end
-- No IPv6 support -- No IPv6 support
if not DDNS.has_ipv6 then if not DDNS.env_info("has_ipv6") then
local v6 = s:option(DummyValue, "_no_ipv6") local v6 = s:option(DummyValue, "_no_ipv6")
v6.titleref = 'http://www.openwrt.org" target="_blank' v6.titleref = 'http://www.openwrt.org" target="_blank'
v6.rawhtml = true v6.rawhtml = true
@ -60,7 +60,7 @@ if not DDNS.has_ipv6 then
end end
-- No HTTPS support -- No HTTPS support
if not DDNS.has_ssl then if not DDNS.env_info("has_ssl") then
local sl = s:option(DummyValue, "_no_https") local sl = s:option(DummyValue, "_no_https")
sl.titleref = DISP.build_url("admin", "system", "packages") sl.titleref = DISP.build_url("admin", "system", "packages")
sl.rawhtml = true sl.rawhtml = true
@ -74,7 +74,7 @@ if not DDNS.has_ssl then
end end
-- No bind_network -- No bind_network
if not DDNS.has_bindnet then if not DDNS.env_info("has_bindnet") then
local bn = s:option(DummyValue, "_no_bind_network") local bn = s:option(DummyValue, "_no_bind_network")
bn.titleref = DISP.build_url("admin", "system", "packages") bn.titleref = DISP.build_url("admin", "system", "packages")
bn.rawhtml = true bn.rawhtml = true
@ -90,7 +90,7 @@ if not DDNS.has_bindnet then
end end
-- currently only cURL possibly without proxy support -- currently only cURL possibly without proxy support
if not DDNS.has_proxy then if not DDNS.env_info("has_proxy") then
local px = s:option(DummyValue, "_no_proxy") local px = s:option(DummyValue, "_no_proxy")
px.titleref = DISP.build_url("admin", "system", "packages") px.titleref = DISP.build_url("admin", "system", "packages")
px.rawhtml = true px.rawhtml = true
@ -104,7 +104,7 @@ if not DDNS.has_proxy then
end end
-- "Force IP Version not supported" -- "Force IP Version not supported"
if not DDNS.has_forceip then if not DDNS.env_info("has_forceip") then
local fi = s:option(DummyValue, "_no_force_ip") local fi = s:option(DummyValue, "_no_force_ip")
fi.titleref = DISP.build_url("admin", "system", "packages") fi.titleref = DISP.build_url("admin", "system", "packages")
fi.rawhtml = true fi.rawhtml = true
@ -112,11 +112,11 @@ if not DDNS.has_forceip then
translate("Force IP Version not supported") .. bold_off translate("Force IP Version not supported") .. bold_off
local value = translate("BusyBox's nslookup and Wget do not support to specify " .. local value = translate("BusyBox's nslookup and Wget do not support to specify " ..
"the IP version to use for communication with DDNS Provider!") "the IP version to use for communication with DDNS Provider!")
if not (DDNS.has_wgetssl or DDNS.has_curl or DDNS.has_fetch) then if not (DDNS.env_info("has_wgetssl") or DDNS.env_info("has_curl") or DDNS.env_info("has_fetch")) then
value = value .. "<br />- " .. value = value .. "<br />- " ..
translate("You should install 'wget' or 'curl' or 'uclient-fetch' package.") translate("You should install 'wget' or 'curl' or 'uclient-fetch' package.")
end end
if not DDNS.has_bindhost then if not DDNS.env_info("has_bindhost") then
value = value .. "<br />- " .. value = value .. "<br />- " ..
translate("You should install 'bind-host' or 'knot-host' or 'drill' package for DNS requests.") translate("You should install 'bind-host' or 'knot-host' or 'drill' package for DNS requests.")
end end
@ -124,7 +124,7 @@ if not DDNS.has_forceip then
end end
-- "DNS requests via TCP not supported" -- "DNS requests via TCP not supported"
if not DDNS.has_bindhost then if not DDNS.env_info("has_bindhost") then
local dt = s:option(DummyValue, "_no_dnstcp") local dt = s:option(DummyValue, "_no_dnstcp")
dt.titleref = DISP.build_url("admin", "system", "packages") dt.titleref = DISP.build_url("admin", "system", "packages")
dt.rawhtml = true dt.rawhtml = true
@ -137,7 +137,7 @@ if not DDNS.has_bindhost then
end end
-- nslookup compiled with musl produce problems when using -- nslookup compiled with musl produce problems when using
if not DDNS.has_dnsserver then if not DDNS.env_info("has_dnsserver") then
local ds = s:option(DummyValue, "_no_dnsserver") local ds = s:option(DummyValue, "_no_dnsserver")
ds.titleref = DISP.build_url("admin", "system", "packages") ds.titleref = DISP.build_url("admin", "system", "packages")
ds.rawhtml = true ds.rawhtml = true
@ -151,7 +151,7 @@ if not DDNS.has_dnsserver then
end end
-- certificates installed -- certificates installed
if DDNS.has_ssl and not DDNS.has_cacerts then if DDNS.env_info("has_ssl") and not DDNS.env_info("has_cacerts") then
local ca = s:option(DummyValue, "_no_certs") local ca = s:option(DummyValue, "_no_certs")
ca.titleref = DISP.build_url("admin", "system", "packages") ca.titleref = DISP.build_url("admin", "system", "packages")
ca.rawhtml = true ca.rawhtml = true

View file

@ -1,21 +1,20 @@
-- Copyright 2014-2018 Christian Schoenebeck <christian dot schoenebeck at gmail dot com> -- Copyright 2014-2018 Christian Schoenebeck <christian dot schoenebeck at gmail dot com>
-- Licensed to the public under the Apache License 2.0. -- Licensed to the public under the Apache License 2.0.
local NXFS = require "nixio.fs"
local DISP = require "luci.dispatcher" local DISP = require "luci.dispatcher"
local HTTP = require "luci.http" local HTTP = require "luci.http"
local SYS = require "luci.sys" local SYS = require "luci.sys"
local CTRL = require "luci.controller.ddns" -- this application's controller local CTRL = require "luci.controller.ddns" -- this application's controller
local DDNS = require "luci.tools.ddns" -- ddns multiused functions local DDNS = require "luci.tools.ddns" -- ddns multiused functions
local show_hints = not (DDNS.has_ipv6 -- IPv6 support local show_hints = not (DDNS.env_info("has_ipv6") -- IPv6 support
and DDNS.has_ssl -- HTTPS support and DDNS.env_info("has_ssl") -- HTTPS support
and DDNS.has_proxy -- Proxy support and DDNS.env_info("has_proxy") -- Proxy support
and DDNS.has_bindhost -- DNS TCP support and DDNS.env_info("has_bindhost") -- DNS TCP support
and DDNS.has_forceip -- Force IP version and DDNS.env_info("has_forceip") -- Force IP version
and DDNS.has_dnsserver -- DNS server support and DDNS.env_info("has_dnsserver") -- DNS server support
and DDNS.has_bindnet -- Bind to network/interface and DDNS.env_info("has_bindnet") -- Bind to network/interface
and DDNS.has_cacerts -- certificates installed at /etc/ssl/certs and DDNS.env_info("has_cacerts") -- certificates installed at /etc/ssl/certs
) )
local not_enabled = not SYS.init.enabled("ddns") local not_enabled = not SYS.init.enabled("ddns")
local need_update = not CTRL.service_ok() local need_update = not CTRL.service_ok()

View file

@ -5,37 +5,135 @@ module("luci.tools.ddns", package.seeall)
local NX = require "nixio" local NX = require "nixio"
local NXFS = require "nixio.fs" local NXFS = require "nixio.fs"
local OPKG = require "luci.model.ipkg"
local UCI = require "luci.model.uci" local UCI = require "luci.model.uci"
local SYS = require "luci.sys" local SYS = require "luci.sys"
local UTIL = require "luci.util"
local function _check_certs() function env_info(type)
local _, v = NXFS.glob("/etc/ssl/certs/*.crt")
if ( v == 0 ) then _, v = NXFS.glob("/etc/ssl/certs/*.pem") end if ( type == "has_ssl" ) or ( type == "has_proxy" ) or ( type == "has_forceip" )
return (v > 0) or ( type == "has_bindnet" ) or ( type == "has_fetch" )
or ( type == "has_wgetssl" ) or ( type == "has_curl" )
or ( type == "has_curlssl" ) or ( type == "has_curlpxy" )
or ( type == "has_fetchssl" ) or ( type == "has_bbwget" ) then
local function has_wgetssl()
return (SYS.call( [[which wget-ssl >/dev/null 2>&1]] ) == 0) -- and true or nil
end
local function has_curlssl()
return (SYS.call( [[$(which curl) -V 2>&1 | grep "Protocols:" | grep -qF "https"]] ) ~= 0)
end
local function has_fetch()
return (SYS.call( [[which uclient-fetch >/dev/null 2>&1]] ) == 0)
end
local function has_fetchssl()
return NXFS.access("/lib/libustream-ssl.so")
end
local function has_curl()
return (SYS.call( [[which curl >/dev/null 2>&1]] ) == 0)
end
local function has_curlpxy()
return (SYS.call( [[grep -i "all_proxy" /usr/lib/libcurl.so* >/dev/null 2>&1]] ) == 0)
end
local function has_bbwget()
return (SYS.call( [[$(which wget) -V 2>&1 | grep -iqF "busybox"]] ) == 0)
end
if type == "has_wgetssl" then
return has_wgetssl()
elseif type == "has_curl" then
return has_curl()
elseif type == "has_curlssl" then
return has_curlssl()
elseif type == "has_curlpxy" then
return has_curlpxy()
elseif type == "has_fetch" then
return has_fetch()
elseif type == "has_fetchssl" then
return has_fetchssl()
elseif type == "has_bbwget" then
return has_bbwget()
elseif type == "has_ssl" then
if has_wgetssl() then return true end
if has_curlssl() then return true end
if (has_fetch() and has_fetchssl()) then return true end
return false
elseif type == "has_proxy" then
if has_wgetssl() then return true end
if has_curlpxy() then return true end
if has_fetch() then return true end
if has_bbwget() then return true end
return false
elseif type == "has_forceip" then
if has_wgetssl() then return true end
if has_curl() then return true end
if has_fetch() then return true end -- only really needed for transfer
return false
elseif type == "has_bindnet" then
if has_curl() then return true end
if has_wgetssl() then return true end
return false
end
elseif ( type == "has_dnsserver" ) or ( type == "has_bindhost" ) or ( type == "has_hostip" ) or ( type == "has_nslookup" ) then
local function has_bindhost()
if (SYS.call( [[which host >/dev/null 2>&1]] ) == 0) then return true end
if (SYS.call( [[which host >/dev/null 2>&1]] ) == 0) then return true end
if (SYS.call( [[which khost >/dev/null 2>&1]] ) == 0) then return true end
if (SYS.call( [[which drill >/dev/null 2>&1]] ) == 0) then return true end
return false
end
local function has_hostip()
return (SYS.call( [[which hostip >/dev/null 2>&1]] ) == 0)
end
local function has_nslookup()
return (SYS.call( [[$(which nslookup) localhost 2>&1 | grep -qF "(null)"]] ) ~= 0)
end
if type == "has_bindhost" then
return has_bindhost()
elseif type == "has_hostip" then
return has_hostip()
elseif type == "has_nslookup" then
return has_nslookup()
elseif tyep == "has_dnsserver" then
if has_bindhost() then return true end
if has_hostip() then return true end
if has_nslookup() then return true end
return false
end
elseif type == "has_ipv6" then
return (NXFS.access("/proc/net/ipv6_route") and NXFS.access("/usr/sbin/ip6tables"))
elseif type == "has_cacerts" then
--old _check_certs() local function
local _, v = NXFS.glob("/etc/ssl/certs/*.crt")
if ( v == 0 ) then _, v = NXFS.glob("/etc/ssl/certs/*.pem") end
return (v > 0)
else
return
end
end end
has_wgetssl = (SYS.call( [[which wget-ssl >/dev/null 2>&1]] ) == 0) -- and true or nil
has_curl = (SYS.call( [[which curl >/dev/null 2>&1]] ) == 0)
has_curlssl = (SYS.call( [[$(which curl) -V 2>&1 | grep "Protocols:" | grep -qF "https"]] ) ~= 0)
has_curlpxy = (SYS.call( [[grep -i "all_proxy" /usr/lib/libcurl.so* >/dev/null 2>&1]] ) == 0)
has_fetch = (SYS.call( [[which uclient-fetch >/dev/null 2>&1]] ) == 0)
has_fetchssl = NXFS.access("/lib/libustream-ssl.so")
has_bbwget = (SYS.call( [[$(which wget) -V 2>&1 | grep -iqF "busybox"]] ) == 0)
has_bindhost = (SYS.call( [[which host >/dev/null 2>&1]] ) == 0)
or (SYS.call( [[which khost >/dev/null 2>&1]] ) == 0)
or (SYS.call( [[which drill >/dev/null 2>&1]] ) == 0)
has_hostip = (SYS.call( [[which hostip >/dev/null 2>&1]] ) == 0)
has_nslookup = (SYS.call( [[$(which nslookup) localhost 2>&1 | grep -qF "(null)"]] ) ~= 0)
has_ipv6 = (NXFS.access("/proc/net/ipv6_route") and NXFS.access("/usr/sbin/ip6tables"))
has_ssl = (has_wgetssl or has_curlssl or (has_fetch and has_fetchssl))
has_proxy = (has_wgetssl or has_curlpxy or has_fetch or has_bbwget)
has_forceip = (has_wgetssl or has_curl or has_fetch) -- only really needed for transfer
has_dnsserver = (has_bindhost or has_hostip or has_nslookup)
has_bindnet = (has_wgetssl or has_curl)
has_cacerts = _check_certs()
-- function to calculate seconds from given interval and unit -- function to calculate seconds from given interval and unit
function calc_seconds(interval, unit) function calc_seconds(interval, unit)
if not tonumber(interval) then if not tonumber(interval) then