Add an (as of yet untested) OC implementation of a Hierarchial Gateway

This commit is contained in:
20kdc 2017-03-20 00:40:28 +00:00
parent c91f3bd2a9
commit 4a4cd485b1
2 changed files with 111 additions and 1 deletions

View File

@ -35,7 +35,9 @@ return {
end,
decode = function (d)
if d:len() < 3 then return end
return d:byte(1), decodeNoHops(d:sub(2))
local src, dst, data = decodeNoHops(d:sub(2))
if not data then return end
return d:byte(1), src, dst, data
end,
decodeNoHops = decodeNoHops
}

108
oc/hierarchi.lua Normal file
View File

@ -0,0 +1,108 @@
-- I, 20kdc, release this into the public domain.
-- No warranty is provided, implied or otherwise.
-- Copper Hierarchial Gateway implementation for OpenComputers.
-- Should be run in a Server Rack, with two servers, connected by Linked Cards.
-- Each should be responsible for "it's" side.
-- This is a piece of dedicated hardware for a specific purpose.
-- The only reason it's not run on two microcontrollers is because
-- they're inconvenient to use and cdlib needs to be there -
-- I'm sure you can port it yourself.
local args = {...}
-- Does the single modem connected to this server connect to the outside world?
local outbound = false
if #args ~= 2 then error("Expecting args: outbound ('true'/'false'), network-name") end
if args[1] == "true" then
outbound = true
elseif args[1] ~= "false" then
error("Only 'true' or 'false' are allowed for the 'outbound' argument.")
end
-- What is the name of this division, including forward-slash?
local netname = args[2] .. "/"
local event = require("event")
local component = require("component")
local cdlib = require("cdlib")
local modem = component.modem
local tunnel = component.tunnel
-- It is possible that this is meant to be used
-- on public wireless infrastructure -
-- for example, if this was a server-level domain,
-- perhaps solely connected via wireless...
-- Oh well. It's the sysadmin's decision to connect it this way.
-- Any wireless-abuse is the local regulator's decision.
if modem.isWireless() then
modem.setStrength(400)
end
modem.open(4957)
-- Rules used on messages coming in from the 'modem' side.
-- (This implies Tunnel packets are trusted absolutely - which is correct.)
local processFrom, processTo
-- Implementation of the rules described in protocol.1 for more or
-- less unambiguous name translation.
if outbound then
processFrom = function (from)
if from:sub(1, netname:len()) == netname then
return
end
return "<" .. from
end
processTo = function (nto)
if from:sub(1, netname:len()) ~= netname then
return
end
return from:sub(netname:len() + 1)
end
else
processFrom = function (from)
if from:sub(1, 1) == "<" then
return
end
return netname .. from
end
processTo = function (nto)
if from:sub(1, 1) ~= "<" then
return
end
return from:sub(2)
end
end
local function checkLen(s)
if s:len() == 0 then return end
if s:len() > 256 then return end
return s
end
while true do
local e = {event.pull("modem_message")}
if e[1] == "modem_message" then
-- type, to, from, port, dist, data
if ((e[2] == tunnel.address) or (e[4] == 4957)) then
local hops, nfrom, nto, data = cdlib.decode(e[6])
if data then
if e[2] == tunnel.address then
-- Pass it on as given.
modem.broadcast(4957, e[6])
elseif e[2] == modem.address then
-- Process it, then give to tunnel
if hops ~= 255 then
local tfrom, tto = checkLen(processFrom(nfrom)), checkLen(processTo(nto))
if tfrom and tto then
tunnel.send(cdlib.encode(hops + 1, tfrom, tto, data))
end
end
end
end
end
end
end