mirror of
https://github.com/XeonSquared/OC-Copper.git
synced 2024-11-23 01:48:06 +11:00
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:
parent
fe66493fd7
commit
b08c897cf8
@ -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)
|
||||
|
@ -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)
|
||||
|
20
protocol.1
20
protocol.1
@ -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.
|
||||
|
43
protocol.2
43
protocol.2
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user