|
|
@@ -10,36 +10,27 @@ sender: original sender of packet |
|
|
|
data: the actual packet data, duh. |
|
|
|
]]-- |
|
|
|
|
|
|
|
local listeners,timers,processes,modems = {},{},{},{} |
|
|
|
local hostname = os.getenv("HOSTNAME") |
|
|
|
local listeners = {} |
|
|
|
local timers = {} |
|
|
|
|
|
|
|
local cfg = {} |
|
|
|
|
|
|
|
local event = require "event" |
|
|
|
local component = require "component" |
|
|
|
local computer = require "computer" |
|
|
|
local serial = require "serialization" |
|
|
|
|
|
|
|
local hostname = computer.address():sub(1,8) |
|
|
|
local modems = {} |
|
|
|
|
|
|
|
local pid = nil |
|
|
|
|
|
|
|
cfg.debug = false |
|
|
|
cfg.port = 4096 |
|
|
|
cfg.retry = 10 |
|
|
|
cfg.retrycount = 64 |
|
|
|
cfg.retrycount = 3 |
|
|
|
cfg.route = true |
|
|
|
|
|
|
|
local event, component, computer, serial = event, component, computer, serial |
|
|
|
local hnpath, cfgpath = "", "" |
|
|
|
|
|
|
|
OPENOS, PSYCHOS, KITTENOS = false, false, false |
|
|
|
if _OSVERSION:sub(1,6) == "OpenOS" then |
|
|
|
OPENOS = true |
|
|
|
hnpath = "/etc/hostname" |
|
|
|
cfgpath = "/etc/minitel.cfg" |
|
|
|
elseif _OSVERSION:sub(1,7) == "PsychOS" then |
|
|
|
PSYCHOS = true |
|
|
|
hnpath = "/boot/cfg/hostname" |
|
|
|
cfgpath = "/boot/cfg/minitel.cfg" |
|
|
|
elseif _OSVERSION:sub(1,8) == "KittenOS" then |
|
|
|
KITTENOS = true |
|
|
|
end |
|
|
|
|
|
|
|
local pcache = {} |
|
|
|
cfg.pctime = 30 |
|
|
|
|
|
|
|
--[[ |
|
|
|
LKR format: |
|
|
|
address { |
|
|
@@ -48,7 +39,6 @@ address { |
|
|
|
time last received |
|
|
|
} |
|
|
|
]]-- |
|
|
|
|
|
|
|
cfg.sroutes = {} |
|
|
|
local rcache = setmetatable({},{__index=cfg.sroutes}) |
|
|
|
cfg.rctime = 15 |
|
|
@@ -66,95 +56,53 @@ packet queue format: |
|
|
|
]]-- |
|
|
|
local pqueue = {} |
|
|
|
|
|
|
|
local function saveconfig() |
|
|
|
if OPENOS or PSYCHOS then |
|
|
|
local f = io.open(cfgpath,"wb") |
|
|
|
if f then |
|
|
|
f:write(serial.serialize(cfg)) |
|
|
|
f:close() |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
local function loadconfig() |
|
|
|
hostname = os.getenv("HOSTNAME") or computer.address():sub(1,8) |
|
|
|
if OPENOS or PSYCHOS then |
|
|
|
local f,g=io.open(hnpath,"rb") |
|
|
|
if f then |
|
|
|
hostname = f:read("*a"):match("(.-)\n") |
|
|
|
f:close() |
|
|
|
end |
|
|
|
local f = io.open(cfgpath,"rb") |
|
|
|
if f then |
|
|
|
local newcfg = serial.unserialize(f:read("*a")) or {} |
|
|
|
f:close() |
|
|
|
for k,v in pairs(newcfg) do |
|
|
|
cfg[k] = v |
|
|
|
end |
|
|
|
else |
|
|
|
saveconfig() |
|
|
|
end |
|
|
|
elseif KITTENOS then |
|
|
|
local globals = neo.requestAccess("x.neo.pub.globals") -- KittenOS standard hostname stuff |
|
|
|
if globals then |
|
|
|
hostname = globals.getSetting("hostname") or hostname |
|
|
|
globals.setSetting("hostname",hostname) |
|
|
|
end |
|
|
|
-- packet cache: [packet ID]=uptime |
|
|
|
local pcache = {} |
|
|
|
cfg.pctime = 30 |
|
|
|
|
|
|
|
local function dprint(...) |
|
|
|
if cfg.debug then |
|
|
|
print(...) |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
if PSYCHOS then -- PsychOS specific code |
|
|
|
serial = require "serialization" |
|
|
|
elseif OPENOS then -- OpenOS specific code |
|
|
|
event = require "event" |
|
|
|
component = require "component" |
|
|
|
computer = require "computer" |
|
|
|
serial = require "serialization" |
|
|
|
listener = false |
|
|
|
elseif KITTENOS then |
|
|
|
neo.requireAccess("s.h.modem_message","pulling packets") |
|
|
|
computer = {["uptime"]=os.uptime,["address"]=os.address} -- wrap computer so the OpenOS code more or less works |
|
|
|
function computer.pushSignal(...) |
|
|
|
for k,v in pairs(processes) do |
|
|
|
v(...) |
|
|
|
end |
|
|
|
local function saveconfig() |
|
|
|
local f = io.open("/boot/cfg/minitel.cfg","wb") |
|
|
|
if f then |
|
|
|
f:write(serial.serialize(cfg)) |
|
|
|
f:close() |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
local function dprint(...) |
|
|
|
if cfg.debug then |
|
|
|
print(...) |
|
|
|
local function loadconfig() |
|
|
|
local f = io.open("/boot/cfg/minitel.cfg","rb") |
|
|
|
if f then |
|
|
|
local newcfg = serial.unserialize(f:read("*a")) |
|
|
|
f:close() |
|
|
|
for k,v in pairs(newcfg) do |
|
|
|
cfg[k] = v |
|
|
|
end |
|
|
|
else |
|
|
|
saveconfig() |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
function start() |
|
|
|
loadconfig() |
|
|
|
hostname = os.getenv("HOSTNAME") or computer.address():sub(1,8) |
|
|
|
print("Hostname: "..hostname) |
|
|
|
if listener then return end |
|
|
|
if OPENOS or PSYCHOS then |
|
|
|
for a,t in component.list("modem") do |
|
|
|
modems[#modems+1] = component.proxy(a) |
|
|
|
end |
|
|
|
for k,v in ipairs(modems) do |
|
|
|
v.open(cfg.port) |
|
|
|
print("Opened port "..cfg.port.." on "..v.address:sub(1,8)) |
|
|
|
end |
|
|
|
for a,t in component.list("tunnel") do |
|
|
|
modems[#modems+1] = component.proxy(a) |
|
|
|
end |
|
|
|
elseif KITTENOS then |
|
|
|
for p in neo.requireAccess("c.modem","networking").list() do -- fun stuff for KittenOS |
|
|
|
dprint(p.address) |
|
|
|
modems[p.address] = p |
|
|
|
end |
|
|
|
for k,v in pairs(modems) do |
|
|
|
v.open(port) |
|
|
|
print("Opened port "..port.." on "..v.address) |
|
|
|
end |
|
|
|
for p in neo.requireAccess("c.tunnel","networking").list() do |
|
|
|
dprint(p.address) |
|
|
|
modems[p.address] = p |
|
|
|
end |
|
|
|
|
|
|
|
if pid then return false end |
|
|
|
|
|
|
|
modems={} |
|
|
|
for a,t in component.list("modem") do |
|
|
|
modems[#modems+1] = component.proxy(a) |
|
|
|
end |
|
|
|
for k,v in ipairs(modems) do |
|
|
|
v.open(cfg.port) |
|
|
|
print("Opened port "..cfg.port.." on "..v.address) |
|
|
|
end |
|
|
|
for a,t in component.list("tunnel") do |
|
|
|
modems[#modems+1] = component.proxy(a) |
|
|
|
end |
|
|
|
|
|
|
|
local function genPacketID() |
|
|
@@ -176,14 +124,15 @@ function start() |
|
|
|
else |
|
|
|
dprint("Not cached", cfg.port,packetID,packetType,dest,sender,vPort,data) |
|
|
|
for k,v in pairs(modems) do |
|
|
|
-- do not send message back to the wired or linked modem it came from |
|
|
|
-- the check for tunnels is for short circuiting `v.isWireless()`, which does not exist for tunnels |
|
|
|
if v.address ~= repeatingFrom or (v.type ~= "tunnel" and v.isWireless()) then |
|
|
|
if v.type == "modem" then |
|
|
|
v.broadcast(cfg.port,packetID,packetType,dest,sender,vPort,data) |
|
|
|
elseif v.type == "tunnel" then |
|
|
|
v.send(packetID,packetType,dest,sender,vPort,data) |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
@@ -255,7 +204,6 @@ function start() |
|
|
|
dprint(npID,table.unpack(pqueue[npID])) |
|
|
|
end |
|
|
|
|
|
|
|
|
|
|
|
local function packetPusher() |
|
|
|
for k,v in pairs(pqueue) do |
|
|
|
if v[5] < computer.uptime() then |
|
|
@@ -273,43 +221,29 @@ function start() |
|
|
|
|
|
|
|
listeners["modem_message"]=processPacket |
|
|
|
listeners["net_send"]=queuePacket |
|
|
|
if OPENOS then |
|
|
|
event.listen("modem_message",processPacket) |
|
|
|
print("Started packet listening daemon: "..tostring(processPacket)) |
|
|
|
event.listen("net_send",queuePacket) |
|
|
|
print("Started packet queueing daemon: "..tostring(queuePacket)) |
|
|
|
timers[#timers+1]=event.timer(0,packetPusher,math.huge) |
|
|
|
print("Started packet pusher: "..tostring(timers[#timers])) |
|
|
|
elseif KITTENOS then |
|
|
|
neo.requireAccess("r.svc.minitel","minitel daemon")(function(pkg,pid,sendSig) |
|
|
|
processes[pid] = sendSig |
|
|
|
return {["sendPacket"]=queuePacket} |
|
|
|
end) |
|
|
|
end |
|
|
|
listeners["net_ack"]=dprint |
|
|
|
|
|
|
|
if KITTENOS or PSYCHOS then |
|
|
|
pid=os.spawn(function() |
|
|
|
while true do |
|
|
|
local ev = {coroutine.yield()} |
|
|
|
packetPusher() |
|
|
|
pruneCache() |
|
|
|
if ev[1] == "k.procdie" then |
|
|
|
processes[ev[3]] = nil |
|
|
|
end |
|
|
|
if listeners[ev[1]] then |
|
|
|
pcall(listeners[ev[1]],table.unpack(ev)) |
|
|
|
end |
|
|
|
end |
|
|
|
end |
|
|
|
end,"minitel") |
|
|
|
print("Started Minitel daemon: "..tostring(pid)) |
|
|
|
return pid |
|
|
|
end |
|
|
|
|
|
|
|
function stop() |
|
|
|
for k,v in pairs(listeners) do |
|
|
|
event.ignore(k,v) |
|
|
|
print("Stopped listener: "..tostring(v)) |
|
|
|
end |
|
|
|
for k,v in pairs(timers) do |
|
|
|
event.cancel(v) |
|
|
|
print("Stopped timer: "..tostring(v)) |
|
|
|
if pid then |
|
|
|
os.kill(pid) |
|
|
|
pid = nil |
|
|
|
return true |
|
|
|
else |
|
|
|
return false |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
@@ -331,11 +265,9 @@ end |
|
|
|
|
|
|
|
function set_route(to,laddr,raddr) |
|
|
|
cfg.sroutes[to] = {laddr,raddr,0} |
|
|
|
saveconfig() |
|
|
|
end |
|
|
|
function del_route(to) |
|
|
|
cfg.sroutes[to] = nil |
|
|
|
end |
|
|
|
|
|
|
|
if not OPENOS then |
|
|
|
start() |
|
|
|
saveconfig() |
|
|
|
end |