mirror of https://github.com/aredn/aredn.git
Improve node setup (#996)
* Reworking the node-setup system - less reboots when changing configuration * Add restart-services to advnet
This commit is contained in:
parent
1e5d933c0d
commit
4120914a60
|
@ -11,7 +11,6 @@
|
|||
/etc/config.mesh/aliases.nat
|
||||
/etc/config.mesh/vtun
|
||||
/etc/config.mesh/wireguard
|
||||
/etc/config.mesh/network_tun
|
||||
/etc/config.mesh/aredn
|
||||
/etc/config.mesh/xlink
|
||||
/etc/config.mesh/metrics
|
||||
|
|
|
@ -2,10 +2,10 @@ config downloads
|
|||
option firmwarepath 'http://downloads.arednmesh.org/firmware'
|
||||
|
||||
config poe
|
||||
option passthrough '0'
|
||||
option passthrough '0'
|
||||
|
||||
config usb
|
||||
option passthrough '1'
|
||||
option passthrough '1'
|
||||
|
||||
config map
|
||||
option leafletjs 'http://unpkg.com/leaflet@0.7.7/dist/leaflet.js'
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
# This file is interpreted as shell script.
|
||||
# Put your custom nft rules here, they will
|
||||
# be executed with each firewall (re-)start.
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ include /etc/aredn_include/static_routes
|
|||
include /etc/config.mesh/xlink
|
||||
|
||||
### Tunnels devices
|
||||
include /etc/config.mesh/network_tun
|
||||
<tun_devices_config>
|
||||
|
||||
### Wireguard
|
||||
<wireguard_network_config>
|
||||
|
|
|
@ -1,79 +0,0 @@
|
|||
config interface 'tun50'
|
||||
option ifname 'tun50'
|
||||
option proto 'none'
|
||||
|
||||
config interface 'tun51'
|
||||
option ifname 'tun51'
|
||||
option proto 'none'
|
||||
|
||||
config interface 'tun52'
|
||||
option ifname 'tun52'
|
||||
option proto 'none'
|
||||
|
||||
config interface 'tun53'
|
||||
option ifname 'tun53'
|
||||
option proto 'none'
|
||||
|
||||
config interface 'tun54'
|
||||
option ifname 'tun54'
|
||||
option proto 'none'
|
||||
|
||||
config interface 'tun55'
|
||||
option ifname 'tun55'
|
||||
option proto 'none'
|
||||
|
||||
config interface 'tun56'
|
||||
option ifname 'tun56'
|
||||
option proto 'none'
|
||||
|
||||
config interface 'tun57'
|
||||
option ifname 'tun57'
|
||||
option proto 'none'
|
||||
|
||||
config interface 'tun58'
|
||||
option ifname 'tun58'
|
||||
option proto 'none'
|
||||
|
||||
config interface 'tun59'
|
||||
option ifname 'tun59'
|
||||
option proto 'none'
|
||||
|
||||
config interface 'tun60'
|
||||
option ifname 'tun60'
|
||||
option proto 'none'
|
||||
|
||||
config interface 'tun61'
|
||||
option ifname 'tun61'
|
||||
option proto 'none'
|
||||
|
||||
config interface 'tun62'
|
||||
option ifname 'tun62'
|
||||
option proto 'none'
|
||||
|
||||
config interface 'tun63'
|
||||
option ifname 'tun63'
|
||||
option proto 'none'
|
||||
|
||||
config interface 'tun64'
|
||||
option ifname 'tun64'
|
||||
option proto 'none'
|
||||
|
||||
config interface 'tun65'
|
||||
option ifname 'tun65'
|
||||
option proto 'none'
|
||||
|
||||
config interface 'tun66'
|
||||
option ifname 'tun66'
|
||||
option proto 'none'
|
||||
|
||||
config interface 'tun67'
|
||||
option ifname 'tun67'
|
||||
option proto 'none'
|
||||
|
||||
config interface 'tun68'
|
||||
option ifname 'tun68'
|
||||
option proto 'none'
|
||||
|
||||
config interface 'tun69'
|
||||
option ifname 'tun69'
|
||||
option proto 'none'
|
|
@ -1,13 +1,11 @@
|
|||
# Server configuration
|
||||
config uhttpd main
|
||||
|
||||
# HTTP listen addresses, multiple allowed
|
||||
list listen_http 0.0.0.0:8080
|
||||
list listen_http 0.0.0.0:80
|
||||
option home /www
|
||||
option rfc1918_filter 1
|
||||
option cgi_prefix /cgi-bin
|
||||
option script_timeout 240
|
||||
option network_timeout 30
|
||||
option tcp_keepalive 5
|
||||
# option config /etc/httpd.conf
|
||||
list listen_http '0.0.0.0:8080'
|
||||
list listen_http '0.0.0.0:80'
|
||||
option home '/www'
|
||||
option rfc1918_filter '1'
|
||||
option cgi_prefix '/cgi-bin'
|
||||
option script_timeout '240'
|
||||
option network_timeout '30'
|
||||
option tcp_keepalive '5'
|
||||
option http_keepalive '0'
|
||||
|
|
|
@ -6,10 +6,13 @@
|
|||
# Example:
|
||||
#
|
||||
# config interface 'xlink0'
|
||||
# option ifname "eth0.500"
|
||||
# option ifname "br0.500"
|
||||
# option proto static
|
||||
# option ipaddr 44.1.2.3
|
||||
# option netmask 255.255.255.0
|
||||
# option netmask 255.255.255.255
|
||||
# option peer 44.1.2.1
|
||||
# option weight 2
|
||||
#
|
||||
# config route
|
||||
# option interface 'xlink0'
|
||||
# option target '44.1.2.1'
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
--[[
|
||||
|
||||
Part of AREDN -- Used for creating Amateur Radio Emergency Data Networks
|
||||
Copyright (C) 2022 Tim Wilkinson
|
||||
Copyright (C) 2022-2023 Tim Wilkinson
|
||||
See Contributors file for additional contributors
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
|
@ -34,76 +34,101 @@
|
|||
|
||||
--]]
|
||||
|
||||
local olsrd_conf = "/tmp/etc/olsrd.conf"
|
||||
require("uci")
|
||||
require("aredn.services")
|
||||
|
||||
-- Load olsrd.conf
|
||||
local lines = {}
|
||||
for line in io.lines(olsrd_conf)
|
||||
local cursor = uci.cursor()
|
||||
|
||||
-- Current nameserver state
|
||||
local ns = cursor:get_all("olsrd", "nameservice")
|
||||
if not ns then
|
||||
print("Missing nameservice")
|
||||
return
|
||||
end
|
||||
local cnames = {}
|
||||
for _, name in ipairs(ns.name)
|
||||
do
|
||||
lines[#lines + 1] = line
|
||||
cnames[name] = true
|
||||
end
|
||||
local chosts = {}
|
||||
for k, v in pairs(ns)
|
||||
do
|
||||
if k:match("^%d+_%d+_%d+_%d+$") then
|
||||
chosts[k:gsub("_", ".")] = v
|
||||
end
|
||||
end
|
||||
local cservices = {}
|
||||
for _, service in ipairs(ns.service or {})
|
||||
do
|
||||
cservices[service] = true
|
||||
end
|
||||
|
||||
-- Generate validated name services
|
||||
local ns = {}
|
||||
for line in io.popen("/usr/local/bin/olsrd-config olsrd validate"):lines()
|
||||
-- Work out the differences between the validated state and the current state
|
||||
local names, hosts, services = aredn.services.get(true)
|
||||
local nnames = false
|
||||
for _, name in ipairs(names)
|
||||
do
|
||||
ns[#ns + 1] = line
|
||||
if cnames[name] then
|
||||
cnames[name] = nil
|
||||
else
|
||||
nnames = true
|
||||
end
|
||||
end
|
||||
local nhosts = {}
|
||||
for _, host in ipairs(hosts)
|
||||
do
|
||||
if chosts[host.ip] then
|
||||
chosts[host.ip] = nil
|
||||
else
|
||||
nhosts[host.ip] = host.host
|
||||
end
|
||||
end
|
||||
local nservices = false
|
||||
for _, service in ipairs(services)
|
||||
do
|
||||
if cservices[service] then
|
||||
cservices[service] = nil
|
||||
else
|
||||
nservices = true
|
||||
end
|
||||
end
|
||||
|
||||
function not_empty(h)
|
||||
for _, _ in pairs(h)
|
||||
do
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
table.remove(ns, 1) -- strip first line which is blank
|
||||
|
||||
-- Locate merge point, then merge new validated services
|
||||
local change = false
|
||||
local i = 1
|
||||
while true
|
||||
do
|
||||
if lines[i] == 'LoadPlugin "olsrd_nameservice.so.0.4"' then
|
||||
local n = 1
|
||||
while i <= #lines and n <= #ns
|
||||
do
|
||||
if lines[i] ~= ns[n] then
|
||||
lines[i] = ns[n]
|
||||
change = true
|
||||
end
|
||||
i = i + 1
|
||||
n = n + 1
|
||||
end
|
||||
if i <= #lines then
|
||||
-- truncated
|
||||
while i <= #lines
|
||||
do
|
||||
table.remove(lines, #lines)
|
||||
end
|
||||
change = true
|
||||
end
|
||||
if n <= #ns then
|
||||
-- append
|
||||
while n <= #ns
|
||||
do
|
||||
lines[#lines + 1] = ns[n]
|
||||
n = n + 1
|
||||
end
|
||||
change = true
|
||||
end
|
||||
break
|
||||
|
||||
-- Apply the changes
|
||||
if nnames or not_empty(cnames) then
|
||||
cursor:set("olsrd", "nameserver", "name", names)
|
||||
change = true
|
||||
end
|
||||
if not_empty(chosts) or not_empty(nhosts) then
|
||||
for k, _ in pairs(chosts)
|
||||
do
|
||||
cursor:delete("olsrd", "nameserver", k)
|
||||
end
|
||||
i = i + 1
|
||||
for k, v in pairs(nhosts)
|
||||
do
|
||||
cursor:set("olsrd", "nameserver", k, v)
|
||||
end
|
||||
change = true
|
||||
end
|
||||
if nservices or not_empty(cservices) then
|
||||
cursor:set("olsrd", "nameserver", "service", services)
|
||||
change = true
|
||||
end
|
||||
|
||||
-- If services have changed we need to update and restart olsrd
|
||||
-- If services have changed we need to restart olsrd
|
||||
if change then
|
||||
cursor:commit("olsrd")
|
||||
print("Change")
|
||||
local f = io.open(olsrd_conf, "w")
|
||||
if f then
|
||||
for _, line in ipairs(lines)
|
||||
do
|
||||
f:write(line .. "\n")
|
||||
end
|
||||
f:close()
|
||||
-- We use 'killall' to restart olsrd to stop if from regenerating the olsrd.conf file we
|
||||
-- just changed. We dont want to modify the standard process so these changes wont persist
|
||||
-- across restarts/reconfigurations but will only be applied daily when poor services are detected
|
||||
os.execute("/usr/bin/killall olsrd > /dev/null 2>&1")
|
||||
end
|
||||
os.execute("/etc/init.d/olsrd restart > /dev/null 2>&1")
|
||||
else
|
||||
print("Unchange")
|
||||
end
|
||||
|
|
|
@ -6,23 +6,6 @@ if [ "$(/sbin/uci -c /etc/config.mesh -q get aredn.@tunnel[0])" != "tunnel" ]; t
|
|||
/sbin/uci -c /etc/config.mesh -q set aredn.@tunnel[0].weight=1
|
||||
/sbin/uci -c /etc/config.mesh -q commit aredn
|
||||
fi
|
||||
clients=$(/sbin/uci -c /etc/config.mesh -q get aredn.@tunnel[0].maxclients)
|
||||
servers=$(/sbin/uci -c /etc/config.mesh -q get aredn.@tunnel[0].maxservers)
|
||||
maxtun=$((49 + $clients + $servers))
|
||||
|
||||
# Check we have sufficient tunnels and regenerate network_tun if not
|
||||
if [ "$(/sbin/uci -c /etc/config.mesh -q get network_tun.tun$maxtun)" != "interface" -o "$(/sbin/uci -c /etc/config.mesh -q get network_tun.tun$((1 + $maxtun)))" != "" ]; then
|
||||
cp /dev/null /etc/config.mesh/network_tun
|
||||
for tun in $(seq 50 $maxtun)
|
||||
do
|
||||
cat >> /etc/config.mesh/network_tun <<__EOT__
|
||||
config interface 'tun$tun'
|
||||
option ifname 'tun$tun'
|
||||
option proto 'none'
|
||||
|
||||
__EOT__
|
||||
done
|
||||
fi
|
||||
|
||||
# Default tunnel weight to 1 (perfect RF)
|
||||
if [ "$(/sbin/uci -c /etc/config.mesh -q get aredn.@tunnel[0].weight)" = "" ]; then
|
||||
|
|
|
@ -670,4 +670,8 @@ function model.set_nvram(var, val)
|
|||
c:commit("hsmmmesh")
|
||||
end
|
||||
|
||||
if not aredn then
|
||||
aredn = {}
|
||||
end
|
||||
aredn.info = model
|
||||
return model
|
||||
|
|
|
@ -0,0 +1,314 @@
|
|||
#! /usr/bin/lua
|
||||
--[[
|
||||
|
||||
Part of AREDN -- Used for creating Amateur Radio Emergency Data Networks
|
||||
Copyright (C) 2021-2023 Tim Wilkinson
|
||||
Original Perl Copyright (C) 2015 Conrad Lara
|
||||
See Contributors file for additional contributors
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation version 3 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Additional Terms:
|
||||
|
||||
Additional use restrictions exist on the AREDN(TM) trademark and logo.
|
||||
See AREDNLicense.txt for more info.
|
||||
|
||||
Attributions to the AREDN Project must be retained in the source code.
|
||||
If importing this code into a new or existing project attribution
|
||||
to the AREDN project must be added to the source code.
|
||||
|
||||
You must not misrepresent the origin of the material contained within.
|
||||
|
||||
Modified versions must be modified to attribute to the original source
|
||||
and be marked in reasonable ways as differentiate it from the original
|
||||
version
|
||||
|
||||
--]]
|
||||
|
||||
require("nixio")
|
||||
require("aredn.utils")
|
||||
require("aredn.hardware")
|
||||
require('aredn.info')
|
||||
require("uci")
|
||||
|
||||
-- Whether to validate hosts and services before publishing
|
||||
local validation_timeout = 150 * 60 -- 2.5 hours (so must fail 3 times in a row)
|
||||
local validation_state = "/tmp/service-validation-state"
|
||||
|
||||
local function ip_to_hostname(ip)
|
||||
if ip and ip ~= "" and ip ~= "none" then
|
||||
local a, b, c, d = ip:match("(.*)%.(.*)%.(.*)%.(.*)")
|
||||
local revip = d .. "." .. c .. "." .. b .. "." .. a
|
||||
local f = io.popen("nslookup " .. ip)
|
||||
if f then
|
||||
local pattern = "^" .. revip .. "%.in%-addr%.arpa%s+name%s+=%s+(%S+)%.local%.mesh"
|
||||
for line in f:lines()
|
||||
do
|
||||
local host = line:match(pattern)
|
||||
if host then
|
||||
f:close()
|
||||
return host
|
||||
end
|
||||
end
|
||||
f:close()
|
||||
end
|
||||
end
|
||||
return ""
|
||||
end
|
||||
|
||||
--
|
||||
-- Get all the known node names, host and services
|
||||
-- with optional validation
|
||||
--
|
||||
local function get(validate)
|
||||
|
||||
local names = {}
|
||||
local hosts = {}
|
||||
local services = {}
|
||||
|
||||
-- canonical names for this node
|
||||
-- (they should up in reverse order, make the official name last)
|
||||
local name = aredn.info.get_nvram("tactical")
|
||||
if name ~= "" then
|
||||
names[#names + 1] = name
|
||||
end
|
||||
name = aredn.info.get_nvram("node")
|
||||
if name ~= "" then
|
||||
names[#names + 1] = name
|
||||
end
|
||||
|
||||
local dmz_mode = uci.cursor("/etc/config.mesh"):get("aredn", "@dmz[0]", "mode")
|
||||
if dmz_mode ~= "0" then
|
||||
if nixio.fs.stat("/etc/config.mesh/aliases.dmz") then
|
||||
for line in io.lines("/etc/config.mesh/aliases.dmz")
|
||||
do
|
||||
local ip, host = line:match("(.*) (.*)")
|
||||
if host then
|
||||
hosts[#hosts + 1] = { ip = ip, host = host }
|
||||
end
|
||||
end
|
||||
end
|
||||
if nixio.fs.stat("/etc/ethers") then
|
||||
local noprop_ip = {}
|
||||
if nixio.fs.stat("/etc/hosts") then
|
||||
for line in io.lines("/etc/hosts")
|
||||
do
|
||||
local ip = line:match("^(%S+)%s.*#NOPROP$")
|
||||
if ip then
|
||||
noprop_ip[ip] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
for line in io.lines("/etc/ethers")
|
||||
do
|
||||
local ip = line:match("[0-9a-fA-F:]+%s+([%d%.]+)")
|
||||
if ip and not noprop_ip[ip] then
|
||||
local host = ip_to_hostname(ip)
|
||||
if host then
|
||||
hosts[#hosts + 1] = { ip = ip, host = host }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- add a name for the dtdlink and xlink interfaces
|
||||
if name then
|
||||
if nixio.fs.stat("/etc/hosts") then
|
||||
for line in io.lines("/etc/hosts")
|
||||
do
|
||||
local dtdip = line:match("^(%d+%.%d+%.%d+%.%d+)%s+dtdlink%.")
|
||||
if dtdip then
|
||||
hosts[#hosts + 1] = { ip = dtdip, host = "dtdlink." .. name .. ".local.mesh" }
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
if nixio.fs.stat("/etc/config.mesh/xlink") then
|
||||
local count = 0
|
||||
uci.cursor("/etc/config.mesh"):foreach("xlink", "interface",
|
||||
function(section)
|
||||
if section.ipaddr then
|
||||
hosts[#hosts + 1] = { ip = section.ipaddr, host = "xlink" .. count .. "." .. name .. ".local.mesh" }
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
-- load the services
|
||||
local servfile = "/etc/config.mesh/_setup.services.nat"
|
||||
if dmz_mode ~= "0" then
|
||||
servfile = "/etc/config.mesh/_setup.services.dmz"
|
||||
end
|
||||
if nixio.fs.access(servfile) then
|
||||
for line in io.lines(servfile)
|
||||
do
|
||||
if not (line:match("^%s*#") or line:match("^%s*$")) then
|
||||
local name, link, proto, host, port, sffx = line:match("(.*)|(.*)|(.*)|(.*)|(.*)|(.*)")
|
||||
if name and name ~= "" and host ~= "" then
|
||||
if proto == "" then
|
||||
proto = "http"
|
||||
end
|
||||
if link == "0" then
|
||||
port = "0"
|
||||
end
|
||||
services[#services + 1] = string.format("%s://%s:%s/%s|tcp|%s\n", proto, host, port, sffx, name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
--
|
||||
|
||||
-- validation
|
||||
if validate then
|
||||
-- Load previous state
|
||||
local vstate = {}
|
||||
if nixio.fs.stat(validation_state) then
|
||||
for line in io.lines(validation_state)
|
||||
do
|
||||
local last, key = line:match("^(%d+) (.*)$")
|
||||
if last then
|
||||
vstate[key] = tonumber(last)
|
||||
end
|
||||
end
|
||||
end
|
||||
local now = os.time()
|
||||
local last = now + validation_timeout
|
||||
local laniface = aredn.hardware.get_iface_name("lan")
|
||||
-- Add in local names so services checks pass
|
||||
for _, name in ipairs(names)
|
||||
do
|
||||
vstate[name:lower()] = last
|
||||
end
|
||||
-- Check we can reach all the IP addresses
|
||||
for _, host in ipairs(hosts)
|
||||
do
|
||||
if os.execute("/bin/ping -q -c 1 -W 1 " .. host.ip .. " > /dev/null 2>&1") == 0 then
|
||||
vstate[host.host:lower()] = last
|
||||
elseif os.execute("/usr/sbin/arping -q -f -c 1 -w 1 -I " .. laniface .. " " .. host.ip .. " > /dev/null 2>&1") == 0 then
|
||||
vstate[host.host:lower()] = last
|
||||
end
|
||||
end
|
||||
-- Check all the services have a valid host
|
||||
for _, service in ipairs(services)
|
||||
do
|
||||
local proto, hostname, port, path = service:match("^(%w+)://([%w%-%.]+):(%d+)(.*)|...|[^|]+$")
|
||||
local vs = vstate[hostname:lower()]
|
||||
if not vs or vs > now or dmz_mode == "0" then
|
||||
if port == "0" then
|
||||
-- no port so not a link - we can only check the hostname so have to assume the service is good
|
||||
vstate[service] = last
|
||||
elseif proto == "http" then
|
||||
-- http so looks like a link. http check it
|
||||
if not hostname:match("%.local%.mesh$") then
|
||||
hostname = hostname .. ".local.mesh"
|
||||
end
|
||||
local status, effective_url = io.popen("/usr/bin/curl --max-time 10 --retry 0 --connect-timeout 2 --speed-time 5 --speed-limit 1000 --silent --output /dev/null --location --write-out '%{http_code} %{url_effective}' " .. "http://" .. hostname .. ":" .. port .. path):read("*a"):match("^(%d+) (.*)")
|
||||
if status == "200" or status == "401" then
|
||||
vstate[service] = last
|
||||
elseif status == "301" or status == "302" or status == "303" or status == "307" or status == "308" then
|
||||
-- Ended at a redirect rather than an actual page.
|
||||
if effective_url:match("^https:") then
|
||||
-- We cannot validate https: links so we just assume they're okay
|
||||
vstate[service] = last
|
||||
end
|
||||
end
|
||||
else
|
||||
-- valid port, but we dont know the protocol (we cannot trust the one defined in the services file because the UI wont set
|
||||
-- anything but 'tcp'). Check both tcp and udp and assume valid it either is okay
|
||||
-- tcp
|
||||
local s = nixio.socket("inet", "stream")
|
||||
s:setopt("socket", "sndtimeo", 2)
|
||||
local r = s:connect(hostname, tonumber(port))
|
||||
s:close()
|
||||
if r == true then
|
||||
-- tcp connection succeeded
|
||||
vstate[service] = last
|
||||
else
|
||||
-- udp
|
||||
s = nixio.socket("inet", "dgram")
|
||||
s:setopt("socket", "rcvtimeo", 2)
|
||||
s:connect(hostname, tonumber(port))
|
||||
s:send("")
|
||||
r = s:recv(0)
|
||||
s:close()
|
||||
if r ~= nil then
|
||||
-- A nil response is an explicity rejection of the udp request. Otherwise we have
|
||||
-- to assume the service is valid
|
||||
vstate[service] = last
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Generate new hosts and services as long as they're valid
|
||||
local old_hosts = hosts
|
||||
hosts = {}
|
||||
for _, host in ipairs(old_hosts)
|
||||
do
|
||||
local lname = host.host:lower()
|
||||
local vs = vstate[lname]
|
||||
if not vs then
|
||||
hosts[#hosts + 1] = host
|
||||
vstate[lname] = last
|
||||
elseif vs > now then
|
||||
hosts[#hosts + 1] = host
|
||||
end
|
||||
end
|
||||
local old_services = services
|
||||
services = {}
|
||||
for _, service in ipairs(old_services)
|
||||
do
|
||||
local vs = vstate[service]
|
||||
if not vs then
|
||||
-- New services will be valid for a while, even if they're not there yet
|
||||
services[#services + 1] = service
|
||||
vstate[service] = last
|
||||
elseif vs > now then
|
||||
services[#services + 1] = service
|
||||
end
|
||||
end
|
||||
|
||||
-- Store state for next time
|
||||
local f = io.open(validation_state, "w")
|
||||
if f then
|
||||
for key, last in pairs(vstate)
|
||||
do
|
||||
f:write(last .. " " .. key .. "\n")
|
||||
end
|
||||
f:close()
|
||||
end
|
||||
end
|
||||
-- end validation
|
||||
|
||||
return names, hosts, services
|
||||
end
|
||||
|
||||
--
|
||||
-- Reset validation
|
||||
--
|
||||
local function reset_validation()
|
||||
os.remove(validation_state)
|
||||
end
|
||||
|
||||
if not aredn then
|
||||
aredn = {}
|
||||
end
|
||||
aredn.services = {
|
||||
get = get,
|
||||
reset_validation = reset_validation
|
||||
}
|
||||
return aredn.services
|
|
@ -311,21 +311,31 @@ function capture(cmd)
|
|||
end
|
||||
|
||||
-- copy a file
|
||||
function filecopy(from, to)
|
||||
function filecopy(from, to, ifchanged)
|
||||
local f = io.open(from, "r")
|
||||
if not f then
|
||||
return false
|
||||
end
|
||||
local r = f:read("*a")
|
||||
f:close()
|
||||
|
||||
if ifchanged then
|
||||
local t = io.open(to, "r")
|
||||
if t then
|
||||
if r == t:read("*a") then
|
||||
t:close()
|
||||
return true, false
|
||||
end
|
||||
t:close()
|
||||
end
|
||||
end
|
||||
local t = io.open(to, "w")
|
||||
if not t then
|
||||
f:close()
|
||||
return false
|
||||
end
|
||||
-- not great on memory usage
|
||||
t:write(f:read("*a"))
|
||||
t:write(r)
|
||||
t:close()
|
||||
f:close()
|
||||
return true
|
||||
return true, true
|
||||
end
|
||||
|
||||
-- remove all files (including recursively into directories)
|
||||
|
@ -345,12 +355,24 @@ function remove_all(name)
|
|||
end
|
||||
|
||||
-- write all data to a file in one go
|
||||
function write_all(filename, data)
|
||||
function write_all(filename, data, ifchanged)
|
||||
if ifchanged then
|
||||
local t = io.open(filename, "r")
|
||||
if t then
|
||||
if data == t:read("*a") then
|
||||
t:close()
|
||||
return true, false
|
||||
end
|
||||
t:close()
|
||||
end
|
||||
end
|
||||
local f = io.open(filename, "w")
|
||||
if f then
|
||||
f:write(data)
|
||||
f:close()
|
||||
return true, true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- read all data from file in one go
|
||||
|
|
|
@ -122,7 +122,7 @@ tmp:close()
|
|||
filecopy("/tmp/.mesh_setup", "/etc/config.mesh/_setup")
|
||||
os.remove("/tmp/.mesh_setup")
|
||||
|
||||
os.execute("/usr/local/bin/node-setup -a mesh")
|
||||
os.execute("/usr/local/bin/node-setup")
|
||||
|
||||
aredn_info.set_nvram("nodeupgraded", "0")
|
||||
print "Rebooting node"
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,397 +0,0 @@
|
|||
#! /usr/bin/lua
|
||||
--[[
|
||||
|
||||
Part of AREDN -- Used for creating Amateur Radio Emergency Data Networks
|
||||
Copyright (C) 2021 Tim Wilkinson
|
||||
Original Perl Copyright (C) 2015 Conrad Lara
|
||||
See Contributors file for additional contributors
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation version 3 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Additional Terms:
|
||||
|
||||
Additional use restrictions exist on the AREDN(TM) trademark and logo.
|
||||
See AREDNLicense.txt for more info.
|
||||
|
||||
Attributions to the AREDN Project must be retained in the source code.
|
||||
If importing this code into a new or existing project attribution
|
||||
to the AREDN project must be added to the source code.
|
||||
|
||||
You must not misrepresent the origin of the material contained within.
|
||||
|
||||
Modified versions must be modified to attribute to the original source
|
||||
and be marked in reasonable ways as differentiate it from the original
|
||||
version
|
||||
|
||||
--]]
|
||||
|
||||
require("nixio")
|
||||
require("aredn.utils")
|
||||
require("aredn.hardware")
|
||||
aredn.info = require('aredn.info')
|
||||
require("uci")
|
||||
|
||||
-- Whether to validate hosts and services before publishing
|
||||
local validate = false
|
||||
local validation_timeout = 150 * 60 -- 2.5 hours (so must fail 3 times in a row)
|
||||
local validation_state = "/tmp/service-validation-state"
|
||||
|
||||
-- check what config gile we are building for
|
||||
local uci_conf_file
|
||||
if #arg == 0 then
|
||||
uci_conf_file = "olsrd"
|
||||
else
|
||||
uci_conf_file = arg[1]
|
||||
if #arg == 2 and arg[2] == "validate" then
|
||||
validate = true
|
||||
end
|
||||
end
|
||||
|
||||
if uci_conf_file == "olsrd6" then
|
||||
-- we only generate entries for IPv4 at the moment
|
||||
os.exit(0)
|
||||
end
|
||||
|
||||
local cursor = uci.cursor()
|
||||
local cursorm = uci.cursor("/etc/config.mesh")
|
||||
|
||||
local names = {}
|
||||
local hosts = {}
|
||||
local services = {}
|
||||
local tunnels = {}
|
||||
local wgtunnels = {}
|
||||
|
||||
function ip_to_hostname(ip)
|
||||
if ip and ip ~= "" and ip ~= "none" then
|
||||
local a, b, c, d = ip:match("(.*)%.(.*)%.(.*)%.(.*)")
|
||||
local revip = d .. "." .. c .. "." .. b .. "." .. a
|
||||
local f = io.popen("nslookup " .. ip)
|
||||
if f then
|
||||
local pattern = "^" .. revip .. "%.in%-addr%.arpa%s+name%s+=%s+(%S+)%.local%.mesh"
|
||||
for line in f:lines()
|
||||
do
|
||||
local host = line:match(pattern)
|
||||
if host then
|
||||
f:close()
|
||||
return host
|
||||
end
|
||||
end
|
||||
f:close()
|
||||
end
|
||||
end
|
||||
return ""
|
||||
end
|
||||
|
||||
-- canonical names for this node
|
||||
-- (they should up in reverse order, make the official name last)
|
||||
local name = aredn.info.get_nvram("tactical")
|
||||
if name ~= "" then
|
||||
names[#names + 1] = name
|
||||
end
|
||||
name = aredn.info.get_nvram("node")
|
||||
if name ~= "" then
|
||||
names[#names + 1] = name
|
||||
end
|
||||
|
||||
local dmz_mode = cursor:get("aredn", "@dmz[0]", "mode")
|
||||
if dmz_mode ~= "0" then
|
||||
if nixio.fs.stat("/etc/config.mesh/aliases.dmz") then
|
||||
for line in io.lines("/etc/config.mesh/aliases.dmz")
|
||||
do
|
||||
local ip, host = line:match("(.*) (.*)")
|
||||
if host then
|
||||
hosts[#hosts + 1] = { ip = ip, host = host }
|
||||
end
|
||||
end
|
||||
end
|
||||
if nixio.fs.stat("/etc/ethers") then
|
||||
local noprop_ip = {}
|
||||
if nixio.fs.stat("/etc/hosts") then
|
||||
for line in io.lines("/etc/hosts")
|
||||
do
|
||||
local ip = line:match("^(%S+)%s.*#NOPROP$")
|
||||
if ip then
|
||||
noprop_ip[ip] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
for line in io.lines("/etc/ethers")
|
||||
do
|
||||
local ip = line:match("[0-9a-fA-F:]+%s+([%d%.]+)")
|
||||
if ip and not noprop_ip[ip] then
|
||||
local host = ip_to_hostname(ip)
|
||||
if host then
|
||||
hosts[#hosts + 1] = { ip = ip, host = host }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- add a name for the dtdlink and xlink interfaces
|
||||
if name then
|
||||
local dtdip = aredn.hardware.get_interface_ip4(aredn.hardware.get_iface_name("dtdlink"))
|
||||
if dtdip then
|
||||
hosts[#hosts + 1] = { ip = dtdip, host = "dtdlink." .. name .. ".local.mesh" }
|
||||
if nixio.fs.stat("/etc/config.mesh/xlink") then
|
||||
local count = 0
|
||||
uci.cursor("/etc/config.mesh"):foreach("xlink", "interface",
|
||||
function(section)
|
||||
if section.ipaddr then
|
||||
hosts[#hosts + 1] = { ip = section.ipaddr, host = "xlink" .. count .. "." .. name .. ".local.mesh" }
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- load the services
|
||||
if nixio.fs.stat("/etc/config/services") then
|
||||
for line in io.lines("/etc/config/services")
|
||||
do
|
||||
if line:match("^%w+://[%w%-%.]+:%d+.*|tcp|[^|]+$") or line:match("^%w+://[%w%-%.]+:%d+.*|udp|[^|]+$") then
|
||||
services[#services + 1] = line
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- validation
|
||||
if validate then
|
||||
-- Load previous state
|
||||
local vstate = {}
|
||||
if nixio.fs.stat(validation_state) then
|
||||
for line in io.lines(validation_state)
|
||||
do
|
||||
local last, key = line:match("^(%d+) (.*)$")
|
||||
if last then
|
||||
vstate[key] = tonumber(last)
|
||||
end
|
||||
end
|
||||
end
|
||||
local now = os.time()
|
||||
local last = now + validation_timeout
|
||||
local laniface = aredn.hardware.get_iface_name("lan")
|
||||
-- Add in local names so services checks pass
|
||||
for _, name in ipairs(names)
|
||||
do
|
||||
vstate[name:lower()] = last
|
||||
end
|
||||
-- Check we can reach all the IP addresses
|
||||
for _, host in ipairs(hosts)
|
||||
do
|
||||
if os.execute("/bin/ping -q -c 1 -W 1 " .. host.ip .. " > /dev/null 2>&1") == 0 then
|
||||
vstate[host.host:lower()] = last
|
||||
elseif os.execute("/usr/sbin/arping -q -f -c 1 -w 1 -I " .. laniface .. " " .. host.ip .. " > /dev/null 2>&1") == 0 then
|
||||
vstate[host.host:lower()] = last
|
||||
end
|
||||
end
|
||||
-- Check all the services have a valid host
|
||||
for _, service in ipairs(services)
|
||||
do
|
||||
local proto, hostname, port, path = service:match("^(%w+)://([%w%-%.]+):(%d+)(.*)|...|[^|]+$")
|
||||
local vs = vstate[hostname:lower()]
|
||||
if not vs or vs > now or dmz_mode == "0" then
|
||||
if port == "0" then
|
||||
-- no port so not a link - we can only check the hostname so have to assume the service is good
|
||||
vstate[service] = last
|
||||
elseif proto == "http" then
|
||||
-- http so looks like a link. http check it
|
||||
if not hostname:match("%.local%.mesh$") then
|
||||
hostname = hostname .. ".local.mesh"
|
||||
end
|
||||
local status, effective_url = io.popen("/usr/bin/curl --max-time 10 --retry 0 --connect-timeout 2 --speed-time 5 --speed-limit 1000 --silent --output /dev/null --location --write-out '%{http_code} %{url_effective}' " .. "http://" .. hostname .. ":" .. port .. path):read("*a"):match("^(%d+) (.*)")
|
||||
if status == "200" or status == "401" then
|
||||
vstate[service] = last
|
||||
elseif status == "301" or status == "302" or status == "303" or status == "307" or status == "308" then
|
||||
-- Ended at a redirect rather than an actual page.
|
||||
if effective_url:match("^https:") then
|
||||
-- We cannot validate https: links so we just assume they're okay
|
||||
vstate[service] = last
|
||||
end
|
||||
end
|
||||
else
|
||||
-- valid port, but we dont know the protocol (we cannot trust the one defined in the services file because the UI wont set
|
||||
-- anything but 'tcp'). Check both tcp and udp and assume valid it either is okay
|
||||
-- tcp
|
||||
local s = nixio.socket("inet", "stream")
|
||||
s:setopt("socket", "sndtimeo", 2)
|
||||
local r = s:connect(hostname, tonumber(port))
|
||||
s:close()
|
||||
if r == true then
|
||||
-- tcp connection succeeded
|
||||
vstate[service] = last
|
||||
else
|
||||
-- udp
|
||||
s = nixio.socket("inet", "dgram")
|
||||
s:setopt("socket", "rcvtimeo", 2)
|
||||
s:connect(hostname, tonumber(port))
|
||||
s:send("")
|
||||
r = s:recv(0)
|
||||
s:close()
|
||||
if r ~= nil then
|
||||
-- A nil response is an explicity rejection of the udp request. Otherwise we have
|
||||
-- to assume the service is valid
|
||||
vstate[service] = last
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Generate new hosts and services as long as they're valid
|
||||
local old_hosts = hosts
|
||||
hosts = {}
|
||||
for _, host in ipairs(old_hosts)
|
||||
do
|
||||
local lname = host.host:lower()
|
||||
local vs = vstate[lname]
|
||||
if not vs then
|
||||
hosts[#hosts + 1] = host
|
||||
vstate[lname] = last
|
||||
elseif vs > now then
|
||||
hosts[#hosts + 1] = host
|
||||
end
|
||||
end
|
||||
local old_services = services
|
||||
services = {}
|
||||
for _, service in ipairs(old_services)
|
||||
do
|
||||
local vs = vstate[service]
|
||||
if not vs then
|
||||
-- New services will be valid for a while, even if they're not there yet
|
||||
services[#services + 1] = service
|
||||
vstate[service] = last
|
||||
elseif vs > now then
|
||||
services[#services + 1] = service
|
||||
end
|
||||
end
|
||||
|
||||
-- Store state for next time
|
||||
local f = io.open(validation_state, "w")
|
||||
if f then
|
||||
for key, last in pairs(vstate)
|
||||
do
|
||||
f:write(last .. " " .. key .. "\n")
|
||||
end
|
||||
f:close()
|
||||
end
|
||||
end
|
||||
-- end validation
|
||||
|
||||
-- load the tunnels
|
||||
if nixio.fs.stat("/etc/local/mesh-firewall/02-vtund") then
|
||||
local tunnum = 50
|
||||
cursor:foreach("vtun", "client",
|
||||
function(section)
|
||||
if section.enabled == "1" then
|
||||
tunnels[#tunnels + 1] = "tun" .. tunnum
|
||||
tunnum = tunnum + 1
|
||||
end
|
||||
end
|
||||
)
|
||||
local maxclients = cursor:get("aredn", "@tunnel[0]", "maxclients")
|
||||
if not maxclients then
|
||||
maxclients = 10
|
||||
end
|
||||
tunnum = 50 + maxclients
|
||||
local wgtunnum = 0
|
||||
if cursor:get("wireguard", "@client[0]", "name") then
|
||||
tunnels[#tunnels + 1] = "wgc"
|
||||
end
|
||||
cursorm:foreach("vtun", "server",
|
||||
function(section)
|
||||
if section.enabled == "1" then
|
||||
if section.netip:match("/") then
|
||||
tunnels[#tunnels + 1] = "wgs" .. wgtunnum
|
||||
wgtunnum = wgtunnum + 1
|
||||
else
|
||||
tunnels[#tunnels + 1] = "tun" .. tunnum
|
||||
tunnum = tunnum + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
-- add the nameservice plugin
|
||||
print()
|
||||
print([[LoadPlugin "olsrd_nameservice.so.0.4"]])
|
||||
print([[{]])
|
||||
print([[ PlParam "sighup-pid-file" "/var/run/dnsmasq/dnsmasq.pid"]])
|
||||
print([[ PlParam "interval" "30"]])
|
||||
print([[ PlParam "timeout" "300"]])
|
||||
print([[ PlParam "name-change-script" "/usr/local/bin/olsrd-namechange"]])
|
||||
for _, name in ipairs(names)
|
||||
do
|
||||
print([[ PlParam "name" "]] .. name .. [["]])
|
||||
end
|
||||
for _, host in ipairs(hosts)
|
||||
do
|
||||
print([[ PlParam "]] .. host.ip .. [[" "]] .. host.host .. [["]])
|
||||
end
|
||||
for _, service in ipairs(services)
|
||||
do
|
||||
print([[ PlParam "service" "]] .. service .. [["]])
|
||||
end
|
||||
print([[}]])
|
||||
|
||||
-- add the ACTIVE tunnel interfaces
|
||||
if #tunnels > 0 then
|
||||
local tun_weight = cursor:get("aredn", "@tunnel[0]", "weight")
|
||||
tun_weight = tonumber(tun_weight)
|
||||
local tuns = ""
|
||||
for _, tunnel in ipairs(tunnels)
|
||||
do
|
||||
tuns = tuns .. " \"" .. tunnel .. "\""
|
||||
end
|
||||
print()
|
||||
print([[Interface]] .. tuns)
|
||||
print([[{]])
|
||||
print([[ Ip4Broadcast 255.255.255.255]])
|
||||
local is_supernode = cursor:get("aredn", "@supernode[0]", "enable") == "1"
|
||||
if not tun_weight or tun_weight < 1 or is_supernode then
|
||||
print([[ Mode "ether"]])
|
||||
elseif tun_weight > 1 then
|
||||
print([[ LinkQualityMult default ]] .. (1 / tun_weight))
|
||||
end
|
||||
print([[}]])
|
||||
end
|
||||
|
||||
-- add the XLINK interfaces
|
||||
if nixio.fs.stat("/etc/config.mesh/xlink") then
|
||||
uci.cursor("/etc/config.mesh"):foreach("xlink", "interface",
|
||||
function(section)
|
||||
print()
|
||||
print([[Interface "]] .. section.ifname .. [["]])
|
||||
print([[{]])
|
||||
if section.peer then
|
||||
print([[ Ip4Broadcast ]] .. section.peer)
|
||||
else
|
||||
print([[ Ip4Broadcast 255.255.255.255]])
|
||||
end
|
||||
local weight = tonumber(section.weight)
|
||||
if weight then
|
||||
if weight > 1 then
|
||||
print([[ LinkQualityMult default ]] .. (1 / weight))
|
||||
elseif weight < 1 then
|
||||
print([[ Mode "ether"]])
|
||||
end
|
||||
else
|
||||
print([[ Mode "ether"]])
|
||||
end
|
||||
print([[}]])
|
||||
end
|
||||
)
|
||||
end
|
|
@ -0,0 +1,70 @@
|
|||
#! /bin/sh
|
||||
true <<'LICENSE'
|
||||
Part of AREDN -- Used for creating Amateur Radio Emergency Data Networks
|
||||
Copyright (C) 2023 Tim Wilkinson
|
||||
See Contributors file for additional contributors
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation version 3 of the License.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Additional Terms:
|
||||
|
||||
Additional use restrictions exist on the AREDN(TM) trademark and logo.
|
||||
See AREDNLicense.txt for more info.
|
||||
|
||||
Attributions to the AREDN Project must be retained in the source code.
|
||||
If importing this code into a new or existing project attribution
|
||||
to the AREDN project must be added to the source code.
|
||||
|
||||
You must not misrepresent the origin of the material contained within.
|
||||
|
||||
Modified versions must be modified to attribute to the original source
|
||||
and be marked in reasonable ways as differentiate it from the original
|
||||
version.
|
||||
|
||||
LICENSE
|
||||
|
||||
ROOT="/tmp/reboot-required"
|
||||
SERVICES="system firewall network wireless dnsmasq tunnels manager olsrd"
|
||||
|
||||
# Anything to do?
|
||||
if [ ! -d $ROOT ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Override services to restart
|
||||
if [ "$*" != "" ]; then
|
||||
SERVICES="$*"
|
||||
fi
|
||||
|
||||
for srv in $SERVICES
|
||||
do
|
||||
if [ -f $ROOT/$srv ]; then
|
||||
echo "Restarting $srv"
|
||||
if [ $srv = "tunnels" ]; then
|
||||
/etc/init.d/vtund restart > /dev/null 2>&1
|
||||
/etc/init.d/vtundsrv restart > /dev/null 2>&1
|
||||
elif [ $srv = "wireless" ]; then
|
||||
/sbin/wifi reload > /dev/null 2>&1
|
||||
elif [ -x /etc/init.d/$srv ]; then
|
||||
/etc/init.d/$srv restart > /dev/null 2>&1
|
||||
fi
|
||||
rm $ROOT/$srv
|
||||
fi
|
||||
done
|
||||
|
||||
rmdir --ignore-fail-on-non-empty $ROOT
|
||||
if [ -d $ROOT ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
|
@ -89,8 +89,7 @@ local settings = {
|
|||
type = "boolean",
|
||||
desc = "Enable <b>Link Quality Management</b><br><br><small>aredn.@lqm[0].enable</small>",
|
||||
default = "1",
|
||||
postcallback = "lqm_defaults()",
|
||||
needreboot = true
|
||||
postcallback = "lqm_defaults()"
|
||||
},
|
||||
{
|
||||
category = "Link Quality Settings",
|
||||
|
@ -145,9 +144,7 @@ local settings = {
|
|||
key = "aredn.@lqm[0].mtu",
|
||||
type = "string",
|
||||
desc = "<b>Maximum packet size</b> in bytes sent over WiFi (256 to 1500)<br><br><small>aredn.@lqm[0].mtu</small>",
|
||||
default = "1500",
|
||||
needreboot = true,
|
||||
nodesetup = true
|
||||
default = "1500"
|
||||
},
|
||||
{
|
||||
category = "Link Quality Settings",
|
||||
|
@ -170,27 +167,21 @@ local settings = {
|
|||
key = "aredn.@wan[0].olsrd_gw",
|
||||
type = "boolean",
|
||||
desc = "<b>Allow other MESH nodes to use my WAN</b> - not recommended and OFF by default<br><br><small>aredn.@wan[0].olsrd_gw</small>",
|
||||
default = "0",
|
||||
needreboot = true,
|
||||
nodesetup = true
|
||||
default = "0"
|
||||
},
|
||||
{
|
||||
category = "WAN Settings",
|
||||
key = "aredn.@wan[0].lan_dhcp_route",
|
||||
type = "boolean",
|
||||
desc = "<b>Allow my LAN devices to access my WAN</b> - ON by default<br><br><small>aredn.@wan[0].lan_dhcp_route</small>",
|
||||
default = "1",
|
||||
needreboot = true,
|
||||
nodesetup = true
|
||||
default = "1"
|
||||
},
|
||||
{
|
||||
category = "WAN Settings",
|
||||
key = "aredn.@wan[0].lan_dhcp_defaultroute",
|
||||
type = "boolean",
|
||||
desc = "<b>Provide default route to LAN devices</b> even when WAN access is disabled<br><br><small>aredn.@wan[0].lan_dhcp_defaultroute</small>",
|
||||
default = "0",
|
||||
needreboot = true,
|
||||
nodesetup = true
|
||||
default = "0"
|
||||
},
|
||||
{
|
||||
category = "WAN Settings",
|
||||
|
@ -200,33 +191,28 @@ local settings = {
|
|||
default = "",
|
||||
condition = "supportsVLANChange()",
|
||||
current = "currentWANVLAN()",
|
||||
postcallback = "changeWANVLAN()",
|
||||
needreboot = true,
|
||||
nodesetup = true
|
||||
postcallback = "changeWANVLAN()"
|
||||
},
|
||||
{
|
||||
category = "WAN Settings",
|
||||
key = "aredn.@wan[0].web_access",
|
||||
type = "boolean",
|
||||
desc = "<b>Enable web access</b> to the node from the WAN interface<br><br><small>aredn.@wan[0].web_access</small>",
|
||||
default = "1",
|
||||
needreboot = true
|
||||
default = "1"
|
||||
},
|
||||
{
|
||||
category = "WAN Settings",
|
||||
key = "aredn.@wan[0].ssh_access",
|
||||
type = "boolean",
|
||||
desc = "<b>Enable SSH access</b> to the node from the WAN interface<br><br><small>aredn.@wan[0].ssh_access</small>",
|
||||
default = "1",
|
||||
needreboot = true
|
||||
default = "1"
|
||||
},
|
||||
{
|
||||
category = "WAN Settings",
|
||||
key = "aredn.@wan[0].telnet_access",
|
||||
type = "boolean",
|
||||
desc = "<b>Enable TELNET access</b> to the node from the WAN interface<br><br><small>aredn.@wan[0].telnet_access</small>",
|
||||
default = "1",
|
||||
needreboot = true
|
||||
default = "1"
|
||||
},
|
||||
{
|
||||
category = "Power Options",
|
||||
|
@ -252,8 +238,7 @@ local settings = {
|
|||
type = "string",
|
||||
desc = "<b>Tunnel Maxclients</b> specifies the maximum number of tunnel clients this node can serve; must be an integer in the range [0,100].<br><br><small>aredn.@tunnel[0].maxclients</small>",
|
||||
default = "10",
|
||||
precallback = "restrictTunnelLimitToValidRange()",
|
||||
postcallback = "adjustTunnelInterfaceCount()"
|
||||
precallback = "restrictTunnelLimitToValidRange()"
|
||||
},
|
||||
{
|
||||
category = "Tunnel Options",
|
||||
|
@ -261,8 +246,7 @@ local settings = {
|
|||
type = "string",
|
||||
desc = "<b>Tunnel Maxservers</b> specifies the maximum number of tunnel servers to which this node can connect; must be an integer in the range [0,100].<br><br><small>aredn.@tunnel[0].maxservers</small>",
|
||||
default = "10",
|
||||
precallback = "restrictTunnelLimitToValidRange()",
|
||||
postcallback = "adjustTunnelInterfaceCount()"
|
||||
precallback = "restrictTunnelLimitToValidRange()"
|
||||
},
|
||||
{
|
||||
category = "Tunnel Options",
|
||||
|
@ -270,7 +254,6 @@ local settings = {
|
|||
type = "string",
|
||||
desc = "<b>Tunnel Weight</b> specifies the cost of using a tunnel. The higher the number, the less likely a tunnel is used.<br><br><small>aredn.@tunnel[0].weight</small>",
|
||||
default = "1",
|
||||
needreboot= true,
|
||||
condition = "not isSupernode()"
|
||||
},
|
||||
{
|
||||
|
@ -278,8 +261,7 @@ local settings = {
|
|||
key = "aredn.@tunnel[0].wanonly",
|
||||
type = "boolean",
|
||||
desc = "<b>WAN-Only Tunnel</b> prevents tunnel traffic from being routed over the Mesh network itself<br><br><small>aredn.@tunnel[0].wanonly</small>",
|
||||
default = "1",
|
||||
needreboot= true
|
||||
default = "1"
|
||||
},
|
||||
{
|
||||
category = "Memory Settings",
|
||||
|
@ -323,8 +305,6 @@ local settings = {
|
|||
type = "string",
|
||||
desc = "<b>Remote logging URL</b> for the remote syslog machine. Must be formatted as <i>protocol://ipaddress:port</i><br><br><small>aredn.@remotelog[0].url</small>",
|
||||
default = "",
|
||||
needreboot = true,
|
||||
nodesetup = true,
|
||||
precallback = "validate_rsyslog()"
|
||||
},
|
||||
{
|
||||
|
@ -455,8 +435,7 @@ local settings = {
|
|||
key = "aredn.@alerts[0].pollrate",
|
||||
type = "string",
|
||||
desc = "<b>Alert Message Pollrate</b> - how many hours to wait between polling for new AREDN Alerts<br><br><small>aredn.@alerts[0].pollrate</small>",
|
||||
default = "1",
|
||||
needreboot = true
|
||||
default = "1"
|
||||
},
|
||||
{
|
||||
category = "AREDN Alert Settings",
|
||||
|
@ -478,37 +457,18 @@ function msg(m)
|
|||
end
|
||||
|
||||
-- uci cursor
|
||||
local cursora = uci.cursor()
|
||||
local cursorb = uci.cursor("/etc/config.mesh")
|
||||
local cursor = uci.cursor("/etc/config.mesh")
|
||||
|
||||
function cursor_set(a, b, c, d)
|
||||
if not cursora:get(a, b) and b:match("@(.+)%[0%]") then
|
||||
cursora:add(a, b:match("@(.+)%[0%]"))
|
||||
if not cursor:get(a, b) and b:match("@(.+)%[0%]") then
|
||||
cursor:add(a, b:match("@(.+)%[0%]"))
|
||||
end
|
||||
cursora:set(a, b, c, d)
|
||||
if not cursorb:get(a, b) and b:match("@(.+)%[0%]") then
|
||||
cursorb:add(a, b:match("@(.+)%[0%]"))
|
||||
end
|
||||
cursorb:set(a, b, c, d)
|
||||
cursora:commit(a)
|
||||
cursorb:commit(a)
|
||||
end
|
||||
|
||||
function cursor_add(a, b, c)
|
||||
cursora:set(a, b, c)
|
||||
cursorb:set(a, b, c)
|
||||
cursora:commit(a)
|
||||
cursorb:commit(a)
|
||||
end
|
||||
|
||||
function cursor_delete(a, b)
|
||||
cursora:delete(a, b)
|
||||
cursorb:delete(a, b)
|
||||
cursora:commit(a)
|
||||
cursorb:commit(a)
|
||||
cursor:set(a, b, c, d)
|
||||
cursor:commit(a)
|
||||
end
|
||||
|
||||
function cursor_get(a, b, c)
|
||||
return cursora:get(a, b, c)
|
||||
return cursor:get(a, b, c)
|
||||
end
|
||||
|
||||
function reboot()
|
||||
|
@ -679,48 +639,6 @@ function restrictTunnelLimitToValidRange()
|
|||
end
|
||||
end
|
||||
|
||||
function addTunnelInterface(file, tunnum)
|
||||
local section = "tun" .. tunnum
|
||||
cursor_add(file, section, "interface")
|
||||
cursor_set(file, section, "ifname", section)
|
||||
cursor_set(file, section, "proto", "none")
|
||||
end
|
||||
|
||||
function deleteTunnelInterface(file, tunnum)
|
||||
local section = "tun" .. tunnum
|
||||
cursor_delete(file, section)
|
||||
end
|
||||
|
||||
function adjustTunnelInterfaceCount()
|
||||
local tunnel_if_count = 0
|
||||
cursora:foreach('network_tun', 'interface', function(s) tunnel_if_count = tunnel_if_count + 1 end)
|
||||
local maxclients = cursor_get("aredn", "@tunnel[0]", "maxclients")
|
||||
if not maxclients then
|
||||
maxclients = 10
|
||||
end
|
||||
local maxservers = cursor_get("aredn", "@tunnel[0]", "maxservers")
|
||||
if not maxservers then
|
||||
maxservers = 10
|
||||
end
|
||||
local needed_if_count = maxclients + maxservers
|
||||
if tunnel_if_count ~= needed_if_count then
|
||||
for i = tunnel_if_count,needed_if_count-1
|
||||
do
|
||||
local tunnum = 50 + i
|
||||
addTunnelInterface("network_tun", tunnum)
|
||||
addTunnelInterface("network", tunnum)
|
||||
end
|
||||
for i = tunnel_if_count-1,needed_if_count,-1
|
||||
do
|
||||
local tunnum = 50 + i
|
||||
deleteTunnelInterface("network_tun", tunnum)
|
||||
deleteTunnelInterface("network", tunnum)
|
||||
end
|
||||
-- can't clone network because it contains macros; re-edit it instead
|
||||
os.execute("sed -i -e '$r /etc/config.mesh/network_tun' -e '/interface.*tun',$d' /etc/config.mesh/network")
|
||||
end
|
||||
end
|
||||
|
||||
function currentWANVLAN()
|
||||
for line in io.lines("/etc/config.mesh/_setup")
|
||||
do
|
||||
|
@ -824,12 +742,8 @@ do
|
|||
if setting.postcallback then
|
||||
loadstring(setting.postcallback)()
|
||||
end
|
||||
if setting.nodesetup then
|
||||
os.execute("/usr/local/bin/node-setup -a mesh")
|
||||
end
|
||||
if setting.needreboot then
|
||||
io.open("/tmp/reboot-required", "w"):close()
|
||||
end
|
||||
os.execute("/usr/local/bin/node-setup > /dev/null 2>&1")
|
||||
os.execute("/usr/local/bin/restart-services.sh > /dev/null 2>&1")
|
||||
break
|
||||
end
|
||||
end
|
||||
|
|
|
@ -358,8 +358,8 @@ if os.getenv("REQUEST_METHOD") == "POST" then
|
|||
end
|
||||
end
|
||||
write_xlink_config(luci.jsonc.parse(params.xlinks))
|
||||
os.execute("/usr/local/bin/node-setup -a mesh > /dev/null 2>&1")
|
||||
io.open("/tmp/reboot-required", "w"):close()
|
||||
os.execute("/usr/local/bin/node-setup > /dev/null 2>&1")
|
||||
os.execute("/usr/local/bin/restart-services.sh > /dev/null 2>&1")
|
||||
end
|
||||
elseif params.op == "defaults" then
|
||||
for _, network in ipairs({ "dtdlink", "lan", "wan" })
|
||||
|
@ -367,8 +367,8 @@ if os.getenv("REQUEST_METHOD") == "POST" then
|
|||
nixio.fs.remove(base .. network .. ".network.user")
|
||||
end
|
||||
write_xlink_config({})
|
||||
os.execute("/usr/local/bin/node-setup -a mesh > /dev/null 2>&1")
|
||||
io.open("/tmp/reboot-required", "w"):close()
|
||||
os.execute("/usr/local/bin/node-setup > /dev/null 2>&1")
|
||||
os.execute("/usr/local/bin/restart-services.sh > /dev/null 2>&1")
|
||||
elseif params.op == "reboot" then
|
||||
reboot()
|
||||
end
|
||||
|
|
|
@ -131,7 +131,7 @@ local hosts = {}
|
|||
local addrs = {}
|
||||
local macs = {}
|
||||
|
||||
if config ~= "mesh" or nixio.fs.stat("/tmp/reboot-required") then
|
||||
if config == "" or nixio.fs.stat("/tmp/reboot-required") then
|
||||
http_header()
|
||||
html.header(node .. " setup", true)
|
||||
html.print("<body><center>")
|
||||
|
@ -814,17 +814,10 @@ if parms.button_save and not (#port_err > 0 or #dhcp_err > 0 or #dmz_err > 0 or
|
|||
|
||||
os.remove("/tmp/service-validation-state")
|
||||
|
||||
if os.execute("/usr/local/bin/node-setup -a -p mesh > /dev/null 2>&1") ~= 0 then
|
||||
if os.execute("/usr/local/bin/node-setup > /dev/null 2>&1") ~= 0 then
|
||||
err("problem with configuration")
|
||||
end
|
||||
if os.execute("/etc/init.d/dnsmasq restart > /dev/null 2>&1") ~= 0 then
|
||||
err("problem with dnsmasq")
|
||||
end
|
||||
if os.execute("/etc/init.d/firewall restart > /dev/null 2>&1") ~= 0 then
|
||||
err("problem with port setup")
|
||||
end
|
||||
if os.execute("/etc/init.d/olsrd restart > /dev/null 2>&1") ~= 0 then
|
||||
err("problem with olsr setup")
|
||||
else
|
||||
os.execute("/usr/local/bin/restart-services.sh dnsmasq firewall olsrd > /dev/null 2>&1")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -816,7 +816,7 @@ if parms.button_save then
|
|||
if not nixio.fs.stat("/tmp/web/save") then
|
||||
nixio.fs.mkdir("/tmp/web/save")
|
||||
end
|
||||
os.execute("/usr/local/bin/node-setup -a " .. parms.config .. " > /tmp/web/save/node-setup.out 2>&1")
|
||||
os.execute("/usr/local/bin/node-setup > /tmp/web/save/node-setup.out 2>&1")
|
||||
if nixio.fs.stat("/tmp/web/save/node-setup.out", "size") > 0 then
|
||||
err(read_all("/tmp/web/save/node-setup.out"))
|
||||
else
|
||||
|
@ -828,7 +828,9 @@ if parms.button_save then
|
|||
f:read("*a")
|
||||
f:close()
|
||||
end
|
||||
io.open("/tmp/reboot-required", "w"):close()
|
||||
if nixio.fs.stat("/tmp/reboot-required") and not nixio.fs.stat("/tmp/reboot-required/reboot") and not nixio.fs.stat("/tmp/unconfigured") then
|
||||
os.execute("/usr/local/bin/restart-services.sh > /dev/null 2>&1")
|
||||
end
|
||||
end
|
||||
if nixio.fs.stat("/tmp/unconfigured") and #errors == 0 then
|
||||
reboot()
|
||||
|
|
|
@ -511,10 +511,8 @@ end
|
|||
if parms.button_save and #cli_err == 0 then
|
||||
cursor:commit("vtun")
|
||||
cursor:commit("wireguard")
|
||||
os.execute("/usr/local/bin/node-setup -a mesh > /dev/null 2>&1")
|
||||
os.execute("/etc/init.d/olsrd restart > /dev/null 2>&1")
|
||||
os.execute("/etc/init.d/vtundsrv restart > /dev/null 2>&1")
|
||||
os.execute("/etc/init.d/network restart > /dev/null 2>&1")
|
||||
os.execute("/usr/local/bin/node-setup > /dev/null 2>&1")
|
||||
os.execute("/usr/local/bin/restart-services.sh olsrd tunnels network > /dev/null 2>&1")
|
||||
end
|
||||
|
||||
local active_tun = get_active_tun()
|
||||
|
|
|
@ -358,10 +358,8 @@ end
|
|||
-- save the connections the uci vtun file
|
||||
if parms.button_save and #conn_err == 0 then
|
||||
cursor:commit("vtun")
|
||||
os.execute("/usr/local/bin/node-setup -a mesh > /dev/null 2>&1")
|
||||
os.execute("/etc/init.d/olsrd restart > /dev/null 2>&1")
|
||||
os.execute("/etc/init.d/vtund restart > /dev/null 2>&1")
|
||||
os.execute("/etc/init.d/network restart > /dev/null 2>&1")
|
||||
os.execute("/usr/local/bin/node-setup > /dev/null 2>&1")
|
||||
os.execute("/usr/local/bin/restart-services.sh olsrd tunnels network > /dev/null 2>&1")
|
||||
end
|
||||
|
||||
local active_tun = get_active_tun()
|
||||
|
|
Loading…
Reference in New Issue