wrote a better copper implementation, the new copper daemon, or ncd for short.
This commit is contained in:
parent
a90114bac1
commit
ff56e4f2f2
@ -11,7 +11,7 @@ modules/lib/print.lua
|
||||
modules/drivers/kbd.lua
|
||||
modules/lib/cdlib.lua
|
||||
modules/lib/relib.lua
|
||||
modules/net/copper.lua
|
||||
modules/net/ncd.lua
|
||||
modules/util/motd.lua
|
||||
modules/lib/readline.lua
|
||||
modules/lib/shutil.lua
|
||||
|
@ -9,7 +9,7 @@ modules/lib/io.lua
|
||||
modules/lib/print.lua
|
||||
modules/lib/cdlib.lua
|
||||
modules/lib/relib.lua
|
||||
modules/net/copper.lua
|
||||
modules/net/ncd.lua
|
||||
modules/util/motd.lua
|
||||
modules/lib/readline.lua
|
||||
modules/lib/shutil.lua
|
||||
|
@ -11,7 +11,7 @@ modules/lib/print.lua
|
||||
modules/drivers/kbd.lua
|
||||
modules/lib/cdlib.lua
|
||||
modules/lib/relib.lua
|
||||
modules/net/copper.lua
|
||||
modules/net/ncd.lua
|
||||
modules/util/motd.lua
|
||||
modules/lib/readline.lua
|
||||
modules/lib/shutil.lua
|
||||
|
156
modules/net/ncd.lua
Normal file
156
modules/net/ncd.lua
Normal file
@ -0,0 +1,156 @@
|
||||
net = {}
|
||||
net.id = computer.address():sub(1,8)
|
||||
net.delay = 2
|
||||
net.np = 4957
|
||||
net.cache = true
|
||||
net.cache_time = 16
|
||||
net.log = false
|
||||
if cdlib and relib then
|
||||
spawn("ncd",function() print(pcall(function()
|
||||
|
||||
local olog = log
|
||||
local function log(...)
|
||||
if net.log then
|
||||
for k,v in ipairs({...}) do
|
||||
olog("[ncd] " .. tostring(v))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local mtab = {} -- modem table
|
||||
local lkr = {} -- LKR cache, contains copper_name = {modem="modem address last received from",addr="address last received from"}
|
||||
local rpackets = {} -- packets that have already been seen
|
||||
local pqueue = {} -- queue for packets to be sent. same format as relib.encode accepts. contains:
|
||||
-- packet_id = {
|
||||
-- pid = "3 char string of random data, same as packet_id",
|
||||
-- addr = "address to send to",
|
||||
-- port = #port number, 0-65535,
|
||||
-- msg = "the packet data",
|
||||
-- wf = "packet ID to wait till ack'd"
|
||||
-- at = #attempts,
|
||||
-- lst = #time of last attempt (USE UPTIME, NOT os.time() BECAUSE WINDOWS IS DUMB)
|
||||
-- }
|
||||
|
||||
for modem in component.list("modem") do
|
||||
mtab[#mtab+1] = modem
|
||||
log("added "..modem)
|
||||
component.invoke(modem,"open",net.np)
|
||||
end
|
||||
|
||||
local function send(addr,msg,hops,src)
|
||||
log("sending packet "..msg.." to "..addr)
|
||||
local src=src or net.id
|
||||
local hops=hops or 0
|
||||
if lkr[addr] and net.cache then
|
||||
component.invoke(lkr[addr].modem,"send",lkr[addr].addr,net.np,"copper",cdlib.encode(hops,src,addr,msg))
|
||||
else
|
||||
for _,modem in ipairs(mtab) do
|
||||
-- log(modem,"broadcast",net.np,hops,net.id,addr,msg,cdlib.encode(hops,net.id,addr,msg))
|
||||
component.invoke(modem,"broadcast",net.np,"copper",cdlib.encode(hops,net.id,addr,msg))
|
||||
end
|
||||
end
|
||||
end
|
||||
local function enqueue(addr,port,msg,waitfor)
|
||||
local qp = {}
|
||||
qp.msg = msg
|
||||
qp.addr = addr
|
||||
qp.port = port
|
||||
qp.wf = waitfor
|
||||
qp.pid = os.gensalt(3)
|
||||
qp.at = 0
|
||||
qp.pt = 1
|
||||
qp.lst = 0
|
||||
pqueue[qp.pid] = qp
|
||||
for k,v in pairs(qp) do log(k.." = "..tostring(v)) end
|
||||
return qp.pid
|
||||
end
|
||||
net.send = enqueue
|
||||
|
||||
local function ppacket(hops,src,dst,data)
|
||||
if not rpackets[src..dst..data] then
|
||||
if dst == net.id then
|
||||
log("packet addressed here")
|
||||
event.push("net_rmsg",src,data)
|
||||
local pd = relib.decode(data)
|
||||
log(pd)
|
||||
if pd then
|
||||
log("valid relib packet")
|
||||
for k,v in pairs(pd) do log(k.." = "..v) end
|
||||
if pd.port and pd.pid and pd.at and pd.pt then
|
||||
if pd.pt == 0 then
|
||||
log("unreliable packet")
|
||||
event.push("net_msg",src,pd.port,pd.msg)
|
||||
elseif pd.pt == 1 then
|
||||
log("reliable packet, sending ack")
|
||||
event.push("net_msg",src,pd.port,pd.msg)
|
||||
pd.pt = 2
|
||||
pd.addr = src
|
||||
pd.lst = 0
|
||||
pd.msg = ""
|
||||
pd.unreliable=true
|
||||
pqueue[pd.pid] = pd
|
||||
for k,v in pairs(pqueue[pd.pid]) do log(k.." = "..tostring(v)) end
|
||||
elseif pd.pt == 2 then
|
||||
log("ack packet: "..pd.pid)
|
||||
pqueue[pd.pid] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif src ~= net.id then
|
||||
if hops < 255 then
|
||||
send(dst,data,hops+1,src)
|
||||
end
|
||||
end
|
||||
rpackets[src..dst..data] = computer.uptime()
|
||||
end
|
||||
end
|
||||
|
||||
while true do
|
||||
local ev = {event.pull()}
|
||||
|
||||
if ev[1] == "rsendmsg" or ev[1] == "sendmsg" or ev[1] == "modem_message" then
|
||||
-- log(table.unpack(ev))
|
||||
end
|
||||
|
||||
if ev[1] == "rsendmsg" then
|
||||
send(ev[2],ev[3])
|
||||
elseif ev[1] == "sendmsg" then
|
||||
table.remove(ev,1)
|
||||
enqueue(table.unpack(ev))
|
||||
elseif ev[1] == "modem_message" and ev[4] == net.np and ev[6] == "copper" then
|
||||
local hops,src,dst,data = cdlib.decode(ev[7])
|
||||
if hops and src and dst and data then
|
||||
if lkr[src] ~= ev[3] then
|
||||
log("lkr["..tostring(src).."] = "..tostring(ev[3]))
|
||||
lkr[src] = {modem=ev[2],addr=ev[3],time=computer.uptime()}
|
||||
end
|
||||
ppacket(hops,src,dst,data)
|
||||
end
|
||||
end
|
||||
|
||||
for k,v in pairs(pqueue) do
|
||||
if computer.uptime() > v.lst+net.delay and pqueue[v.wf] == nil then
|
||||
send(v.addr,relib.encode(v))
|
||||
v.lst = computer.uptime()
|
||||
v.at = v.at+1
|
||||
if v.at > 254 then
|
||||
pqueue[k] = nil
|
||||
end
|
||||
if v.unreliable then pqueue[k] = nil end
|
||||
end
|
||||
end
|
||||
|
||||
for k,v in pairs(lkr) do
|
||||
if computer.uptime() > v.time+net.cache_time then
|
||||
lkr[k] = nil
|
||||
end
|
||||
end
|
||||
for k,v in pairs(rpackets) do
|
||||
if computer.uptime() > v+net.cache_time then
|
||||
rpackets[k] = nil
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end)) end)
|
||||
end
|
Loading…
Reference in New Issue
Block a user