Change hierarchi char from '<' to '^', fix some issues

This is kind of untested. I've asked Izaya to test it...
This commit is contained in:
20kdc 2017-09-02 14:51:34 +01:00
parent fe66493fd7
commit b08c897cf8
5 changed files with 94 additions and 26 deletions

View File

@ -71,9 +71,9 @@ processFrom = function (incoming, from)
if from:sub(1, netname:len()) == netname then if from:sub(1, netname:len()) == netname then
return return
end end
return "<" .. from return "^" .. from
else else
if from:sub(1, 1) == "<" then if from:sub(1, 1) == "^" then
return return
end end
return netname .. from return netname .. from
@ -86,7 +86,7 @@ processTo = function (incoming, nto)
end end
return nto:sub(netname:len() + 1) return nto:sub(netname:len() + 1)
else else
if nto:sub(1, 1) ~= "<" then if nto:sub(1, 1) ~= "^" then
return return
end end
return nto:sub(2) return nto:sub(2)

View File

@ -28,8 +28,8 @@ local function verify(d)
local hops, src, dst, data = cdlib.decode(d) local hops, src, dst, data = cdlib.decode(d)
if not data then return end if not data then return end
-- Just a bit of filtering -- Just a bit of filtering
if dst:sub(1, 1) ~= "<" then return end if dst:sub(1, 1) ~= "^" then return end
if d:len() > 2021 then return end if d:len() > 2022 then return end
return true return true
end end
@ -55,10 +55,17 @@ local function readerRoutine()
for i = 1, sz do for i = 1, sz do
dat = dat .. readByte() dat = dat .. readByte()
end end
md.broadcast(4957, "copper", dat) if dat ~= "" then
md.broadcast(4957, "copper", dat)
end
end end
end end
event.timer(10, function ()
tcp:write("\x00\x00")
tcp:flush()
end, math.huge)
local primary = coroutine.create(readerRoutine) local primary = coroutine.create(readerRoutine)
while true do while true do
local et, _, _, p, _, m, d = event.pull(0.1) local et, _, _, p, _, m, d = event.pull(0.1)

View File

@ -3,14 +3,17 @@ Copper Protocol :: Hierarchial Gateways
"Hierarchial Gateways" are a system for ISP-like bodies to prevent their "Hierarchial Gateways" are a system for ISP-like bodies to prevent their
users from causing havoc. users from causing havoc.
Note that this is not the only possible system, and implementors can do as they wish regarding addressing.
(However, for this reason, applications should allow specification of a prefix to all "internet"-level addresses.)
They are simply base low-level Copper nodes with two interfaces and the They are simply base low-level Copper nodes with two interfaces and the
following rules: following rules:
For the FROM address: For the FROM address:
If it's on the parent side, reject if it's prefixed with hostname .. "/", If it's on the parent side, reject if it's prefixed with hostname .. "/",
otherwise prefix it with "<". otherwise prefix it with "^".
If it's on the child side, reject if it's prefixed with "<", If it's on the child side, reject if it's prefixed with "^",
otherwise prefix it with hostname .. "/". otherwise prefix it with hostname .. "/".
For the TO address: For the TO address:
@ -18,11 +21,11 @@ If it's on the child side, reject if it's prefixed with "<",
If it's on the parent side, reject unless prefixed with hostname .. "/", If it's on the parent side, reject unless prefixed with hostname .. "/",
otherwise remove that. otherwise remove that.
(Optionally, if the name is "*", bypass this rule completely. (Optionally, if the name is "*", bypass this rule completely.
This is not recommended, though, as this allows sending a "complete broadcast packet" via "[some amount of <]*".) This is not recommended, though, as this allows sending a "complete broadcast packet" via "[some amount of ^]*".)
If it's on the child side, reject unless prefixed with "<", If it's on the child side, reject unless prefixed with "^",
otherwise remove that. otherwise remove that.
(Optionally, if the name is "<*", reject anyway. (Optionally, if the name is "^*", reject anyway.
This is a measure which you may or may not wish to take - if the above 'complete broadcast' possibility has been implemented, then it is a must.) This is a measure which you may or may not wish to take - if the above 'complete broadcast' possibility has been implemented, then it is a must.)
For the packet's general routing: For the packet's general routing:
@ -54,3 +57,10 @@ Possible uses of hierarchial gateways:
following the same protocol as everything else in Copper, following the same protocol as everything else in Copper,
unlike certain competitors unlike certain competitors
2. ISPs within servers, perhaps those using the hubs 2. ISPs within servers, perhaps those using the hubs
Errata:
Previous versions of the spec used "<" - this was not very usable from most shells on most operating systems.
It has been replaced with "^".
It was not explicitly specified that this was not the only way of doing things - this has been corrected.

View File

@ -37,6 +37,10 @@ Combined with correctly-forgetting packet caches, this should prevent
The final header byte is the actual indicator of what is in the packet. The final header byte is the actual indicator of what is in the packet.
There are two sections of packet types:
-- Basic Datagrams
0x00 indicates that this is an unreliable packet. 0x00 indicates that this is an unreliable packet.
0x01 indicates that this is a reliable packet, expecting acknowledgement. 0x01 indicates that this is a reliable packet, expecting acknowledgement.
0x02 indicates that this is an acknowledgement for a reliable packet. 0x02 indicates that this is an acknowledgement for a reliable packet.
@ -59,7 +63,46 @@ Bob receives it successfully on the second time, and sends back a
Alice receives the response and does not send a third packet. Alice receives the response and does not send a third packet.
-- Connections
0x03 : Request Connection Start
This is similar to an 0x01 reliable packet expecting acknowledgement in how it is to be sent,
including the usual packetID randomization, and multiple attempts.
However, the data must be two bytes, and these first two bytes must be the new port number.
The port numbers that ought to be used for active connections are 0x8000 to 0xFFFF.
The response must be on that port number.
0x04 : Request Connection Start / Response
This is sent on the port given by a Request Connection Start to accept the connection.
It has the same format as 0x03 (new port number).
This establishes the connection, and data transmission can begin.
Connections die if no packets have been received by either side for at least 60 seconds.
It is recommended the connection "ping" every 15 seconds.
- The following packets have the current sequence number as their packetID.
This variable is per-connection-side, starts at 0,
and is incremented after a Connection Data packet
sent by that side.
0x05 : Connection Data
If 0 bytes, this serves as a ping (not a packet)
The sender's sequence number is incremented by 1 before sending.
The reply is a Connection Acknowledgement with the same sequence number (but no data)
0x06 : Connection Resequencing
Specifies that the next data packet's sequence number is going to be 0.
(The packet has the current sequence number, to put it in context.)
It is this in particular which requires connections keep:
1. A map of sequence number -> data (flushed when data is read)
2. A list of sequence numbers to read.
When ready, a connection data acknowledgement should be given with sequence number 0.
0x07 : Connection Data Acknowledgement
Sent from the target of 0x05/0x06 to the sender. For 0x05, has the sequence number of the associated data.
ERRATA: ERRATA:
When this document was originally posted, the relib header was described as 6 bytes despite a total of 7 bytes being specified. When this document was originally posted, the relib header was described as 6 bytes despite a total of 7 bytes being specified.
Thanks to @skyem123 for finding the issue. Thanks to @skyem123 for finding the issue.
The "Connections" section is a recent extension (August 28th 2017)

View File

@ -35,14 +35,17 @@ local function getpacket(s)
local l = getbyte(s) local l = getbyte(s)
if not l then error("framing bad") end if not l then error("framing bad") end
local sz = string.byte(l) + (string.byte(h) * 256) local sz = string.byte(l) + (string.byte(h) * 256)
if sz > 2021 then error("packet too large") end if sz > 2022 then error("packet too large") end
local data = "" local data = ""
for i = 1, sz do for i = 1, sz do
local dbt = getbyte(s) local dbt = getbyte(s)
if not dbt then error("terminated early") end if not dbt then error("terminated early") end
data = data .. dbt data = data .. dbt
end end
return cdlib.decode(data) if data == "" then
return false
end
return true, cdlib.decode(data)
end end
local function checkLen(name) local function checkLen(name)
@ -52,10 +55,10 @@ local function checkLen(name)
end end
local function translateSend(hops, src, dst, data, srname, tgsock, tgname) local function translateSend(hops, src, dst, data, srname, tgsock, tgname)
if src:sub(1, 1) == "<" then return end if src:sub(1, 1) == "^" then return end
if dst:sub(1, tgname:len() + 2) ~= "<" .. tgname .. "/" then return end if dst:sub(1, tgname:len() + 2) ~= "^" .. tgname .. "/" then return end
-- Ok, all rejection rules have been handled -- Ok, all rejection rules have been handled
src = "<" .. srname .. "/" .. src src = "^" .. srname .. "/" .. src
dst = dst:sub(tgname:len() + 3) dst = dst:sub(tgname:len() + 3)
src, dst = checkLen(src), checkLen(dst) src, dst = checkLen(src), checkLen(dst)
if src and dst then if src and dst then
@ -82,19 +85,24 @@ local function messageroutine(tbl)
print("confirmed name " .. name) print("confirmed name " .. name)
tbl[3] = name tbl[3] = name
while true do while true do
local hops, src, dst, data = getpacket(tbl[2]) local rcv, hops, src, dst, data = getpacket(tbl[2])
if not data then if rcv then
error("Bad Copper packet") if not data then
end error("Bad Copper packet")
print("packet", src, dst) end
if hops ~= 255 then print("packet", src, dst)
for _, v in ipairs(sockets) do if hops ~= 255 then
if v[3] then for _, v in ipairs(sockets) do
if v ~= tbl then if v[3] then
translateSend(hops + 1, src, dst, data, name, v[2], v[3]) if v ~= tbl then
translateSend(hops + 1, src, dst, data, name, v[2], v[3])
end
end end
end end
end end
else
-- Ping response
tbl[2]:send("\x00\x00")
end end
end end
end end