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
return
end
return "<" .. from
return "^" .. from
else
if from:sub(1, 1) == "<" then
if from:sub(1, 1) == "^" then
return
end
return netname .. from
@ -86,7 +86,7 @@ processTo = function (incoming, nto)
end
return nto:sub(netname:len() + 1)
else
if nto:sub(1, 1) ~= "<" then
if nto:sub(1, 1) ~= "^" then
return
end
return nto:sub(2)

View File

@ -28,8 +28,8 @@ local function verify(d)
local hops, src, dst, data = cdlib.decode(d)
if not data then return end
-- Just a bit of filtering
if dst:sub(1, 1) ~= "<" then return end
if d:len() > 2021 then return end
if dst:sub(1, 1) ~= "^" then return end
if d:len() > 2022 then return end
return true
end
@ -55,10 +55,17 @@ local function readerRoutine()
for i = 1, sz do
dat = dat .. readByte()
end
md.broadcast(4957, "copper", dat)
if dat ~= "" then
md.broadcast(4957, "copper", dat)
end
end
end
event.timer(10, function ()
tcp:write("\x00\x00")
tcp:flush()
end, math.huge)
local primary = coroutine.create(readerRoutine)
while true do
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
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
following rules:
For the FROM address:
If it's on the parent side, reject if it's prefixed with hostname .. "/",
otherwise prefix it with "<".
If it's on the child side, reject if it's prefixed with "<",
otherwise prefix it with "^".
If it's on the child side, reject if it's prefixed with "^",
otherwise prefix it with hostname .. "/".
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 .. "/",
otherwise remove that.
(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.
(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.)
For the packet's general routing:
@ -54,3 +57,10 @@ Possible uses of hierarchial gateways:
following the same protocol as everything else in Copper,
unlike certain competitors
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.
There are two sections of packet types:
-- Basic Datagrams
0x00 indicates that this is an unreliable packet.
0x01 indicates that this is a reliable packet, expecting acknowledgement.
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.
-- 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:
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.
The "Connections" section is a recent extension (August 28th 2017)

View File

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