local json = require 'jsonc' local site = require 'gluon.site' local util = require 'gluon.util' local function parse_ip(addr) if not addr then return end local ip4 = {addr:match('(%d+)%.(%d+)%.(%d+)%.(%d+)')} if ip4[1] then local ret = {} for i, part in ipairs(ip4) do ret[i] = tonumber(part) end return ret end if not addr:match('^[:%x]+$') then return end if addr:sub(0, 2) == '::' then addr = '0' .. addr end if addr:sub(-2) == '::' then addr = addr .. '0' end addr = addr .. ':' local groups, groups1 = {}, {} for part in addr:gmatch('([^:]*):') do if part == '' then groups1 = groups groups = {} else groups[#groups+1] = tonumber(part, 16) end end while #groups + #groups1 < 8 do groups1[#groups1+1] = 0 end for _, group in ipairs(groups) do groups1[#groups1+1] = group end return groups1 end local function match(a, b, n) if not a or not b then return false end for i = 1, n do if a[i] ~= b[i] then return false end end return true end entry({}, call(function(http, renderer) local nodeinfo = json.parse(util.exec('exec gluon-neighbour-info -d ::1 -p 1001 -t 1 -c 1 -r nodeinfo')) local node_ip = parse_ip(http:getenv('SERVER_ADDR')) if node_ip then if match(node_ip, parse_ip(site.next_node.ip6()), 8) then -- The user has visited the status page via the ipv6 next-node address -- Redirect the user to a unique ipv6 address to avoid switching nodes -- if there is an address matching the first 64bit of the requesting address local remote_ip = parse_ip(http:getenv('REMOTE_ADDR')) if remote_ip then for _, addr in ipairs(nodeinfo.network.addresses) do if match(remote_ip, parse_ip(addr), 4) then http:header('Cache-Control', 'no-cache, no-store, must-revalidate') http:redirect('http://[' .. addr .. ']' .. http:getenv('REQUEST_URI')) http:close() return end end end end if match(node_ip, parse_ip(site.next_node.ip4()), 4) then -- The user has visited the status page via the ipv4 next-node address -- Redirect the user to our unique ipv4 address to avoid switching nodes local process = io.popen('ip -br -4 address show br-client', 'r') if process then local output = process:read('*a') process:close() if output then local addr = string.match(output, '%d+%.%d+%.%d+%.%d+') if addr then http:header('Cache-Control', 'no-cache, no-store, must-revalidate') http:redirect('http://' .. addr .. http:getenv('REQUEST_URI')) http:close() return end end end end end renderer.render('status-page', { nodeinfo = nodeinfo, site = site }, 'gluon-status-page') end))