-- 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 nto:sub(1, netname:len()) ~= netname then return end return nto: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 nto:sub(1, 1) ~= "<" then return end return nto:sub(2) end end local function checkLen(s) if not s then return end 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, magic[6], data[7] if ((e[2] == tunnel.address) or (e[4] == 4957)) then if e[6] == "copper" then if type(e[7]) == "string" then local hops, nfrom, nto, data = cdlib.decode(e[7]) if data then if e[2] == tunnel.address then -- Pass it on as given. modem.broadcast(4957, "copper", e[7]) 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("copper", cdlib.encode(hops + 1, tfrom, tto, data)) end end end end end end end end end